Dumb String Conversion Problem?

  • Thread starter Thread starter Fred Hebert
  • Start date Start date
F

Fred Hebert

I have a function that requires a LPCTSTR parameter. I have the value I
want to pass to it in a TextBox->Text field. Is there any way to do it in
a single assignment.

e.g.
DWORD Xyz::TheFunc(LPCTSTR lpVal)
....
TheFunc(Junk->Text->Something());
 
Fred said:
I have a function that requires a LPCTSTR parameter. I have the value I
want to pass to it in a TextBox->Text field. Is there any way to do it in
a single assignment.
No.

e.g.
DWORD Xyz::TheFunc(LPCTSTR lpVal)
...
TheFunc(Junk->Text->Something());

See: Convert from System::String* to TCHAR*/CString
http://blog.kalmbachnet.de/?postid=18

<code>
#include <vcclr.h>

System::String *mstr = Junk->Text->Something();
TCHAR *ustr;
#ifdef _UNICODE
ustr = new TCHAR[mstr->get_Length()+1];
const __wchar_t __pin * umstring = PtrToStringChars(mstr);
#else
const char* umstring = (const
char*)Marshal::StringToHGlobalAnsi(mstr).ToPointer();
ustr = new TCHAR[strlen(umstring)+1];
#endif
_tcscpy(ustr, umstring);
#ifndef _UNICODE
Marshal::FreeHGlobal(IntPtr((void*)umstring));
#endif

// do something with the unmanaged string
TheFunc(ustr);

delete [] ustr;

</code>

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
This seems to be the source of the many people's frustration (including my
own at one point). I would recommend Microsoft think seriously about putting
in some String* to char[] 'standard' .NET function (realizing they have no
control over the C++ standard itself). Or, better yet, overload assignment
(=) for 'char[]' to allow code like:

String* string_thing = "test" ;
char[33] char_array = string_thing ;

'char_array' would then have "test" as a null-terminated old-style string...

I realize the problem is 'char' came before 'String*', so 'char' knows
nothing about 'String*' (although the reverse is not true, which is why the
'string_thing' definition above is valid). But eqully, since 'char' came
first, much legacy stuff depends on 'char' still, while modern day usage of
'String*' is prominent (ala Control text fields). Conversion I think is
essential, and shouldn't look complex or complicated, and should be doable
in one line of C++ code...

My 2 cents...

[==Peteroid==]
 
Fred said:
I have a function that requires a LPCTSTR parameter. I have the value I
want to pass to it in a TextBox->Text field. Is there any way to do it in
a single assignment.

e.g.
DWORD Xyz::TheFunc(LPCTSTR lpVal)
...
TheFunc(Junk->Text->Something());

The easiest way is to use the CString-Class:

<code>
#include <afx.h>

TheFunc(CString(Junk->Text->Something());
</code>

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
Hi Peteroid!
I realize the problem is 'char' came before 'String*', so 'char' knows
nothing about 'String*'

The OP was about TCHAR, not char. But in general you are right.
Conversion I think is
essential, and shouldn't look complex or complicated, and should be doable
in one line of C++ code...

You are right. Therefor MS provided the "CString"-class which handles
the conversion icely:

System::String *mstring = S"Hello world";
// this works:
CString s1(mstring);
// and even the following works:
CString s2;
s2 = mstring;

This also handles ANSI/UNICODE builds.

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
The easiest way is to use the CString-Class:

<code>
#include <afx.h>

TheFunc(CString(Junk->Text->Something());
</code>

This is what is driving me nuts.

You can't "#include <afx.h>" if you also "#include <windows.h>"...

This is what I have to do:
char* junk = (char*)(void*)Marshal::StringToHGlobalAnsi(Junk->Text);
TheFunc(junk);
Marshal::FreeHGlobal(junk);

To me this seems like an abomination.

In other "environments" (non MS) all I have to do is:
TheFunc(Junk->Text.c_str());
or
TheFunc(PChar(Junk.Text));

If MS wants people to migrate they need to make the transition easier.
At this point my evaluation of our company switching to Visual Studio is
that it is going to be very expensive to migrate our stuff and insane to
throw away 16 years of code and start over.

Am I missing something?
 
Hi Fred!
This is what I have to do:
char* junk = (char*)(void*)Marshal::StringToHGlobalAnsi(Junk->Text);
TheFunc(junk);
Marshal::FreeHGlobal(junk);

Remember: This *only* works if you make an ANSI-Build of your App! If
you (later) switch to UNICODE, it does not work anymore!

You can't "#include <afx.h>" if you also "#include <windows.h>"...

What is the problem? The following works perfectly:

#include <afx.h>
#include <windows.h>
In other "environments" (non MS) all I have to do is:
TheFunc(PChar(Junk.Text));

This is exactly what I suggested:
TheFunc(CString(Junk.Text));

Am I missing something?

Maybe; I have not looked at your source...

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
Hi Fred!

Remember: This *only* works if you make an ANSI-Build of your App! If
you (later) switch to UNICODE, it does not work anymore!



What is the problem? The following works perfectly:

#include <afx.h>
#include <windows.h>


This is exactly what I suggested:
TheFunc(CString(Junk.Text));



Maybe; I have not looked at your source...

On my Visual Studio 2003 Enterprise running on XP PRO SP2, putting
"#include <afx.h>" before "#include <windows.h>" results in about dozen
warnings and errors. Reversing the order results in only one error in
afxv_w32.h which is generated by the following lines of code:

#ifdef _WINDOWS_
#error WINDOWS.H already included. MFC apps must not #include
<windows.h>
#endif

Since this is a .net app I don't fully understand this error.

Also you mentioned ANSI/UNICODE builds, where is this set?

I am an experienced programmer, but new to .net. I am probably doing
something wrong, but I find the documentation is poor and most of the
examples are to simplistic especially when it comes to mixed mode
programming.

Most of our applications are evolutions of existing apps rather than new
application from scratch. I suspect most companies who have a large
investment in code are not going to switch to .net unless there is a
reasonable upgrade path. So far I don't see it. It has been an up hill
battle just to convert these little demo programs that I originally
wrote in an hour or 2. I can't imagine what it would be like to convert
one of our multi-threaded DLLs that took a week to write. I could
probably retire converting one of our major apps, some of which took
more than a year to write.

I had fewer problems converting these program to Linux using a free
compiler! It's just a char* so why all the grief.
 
Hi Fred!
On my Visual Studio 2003 Enterprise running on XP PRO SP2, putting
"#include <afx.h>" before "#include <windows.h>" results in about dozen
warnings and errors. Reversing the order results in only one error in
afxv_w32.h which is generated by the following lines of code:

It is also enoght to only include "afx.h". You do not need to include
"windows.h", because it is already included by "afx.h".
Also you mentioned ANSI/UNICODE builds, where is this set?

Right-Click on the project, select "Properties".
In the "General" section you see an entry called "Character Set". Here
you can select "Not Set", "Multi-Byte", "Unicode"
I am an experienced programmer, but new to .net.

Unicode is not new... this option was available at least since VC5 (or
NT 3.1).
Most of our applications are evolutions of existing apps rather than new
application from scratch. I suspect most companies who have a large
investment in code are not going to switch to .net unless there is a
reasonable upgrade path. So far I don't see it. It has been an up hill
battle just to convert these little demo programs that I originally
wrote in an hour or 2. I can't imagine what it would be like to convert
one of our multi-threaded DLLs that took a week to write. I could
probably retire converting one of our major apps, some of which took
more than a year to write.

From my expirience, a reasonable upgrade is only if you use your
existing code via P/Invoke / COM-Interop and (re)write new/old parts in
C# (for example UI).

I had fewer problems converting these program to Linux using a free
compiler! It's just a char* so why all the grief.

That might be true. But you do not have all the advantages of .NET (like
reflection, which is really a bit plus!).
And you also need to reqrite your UI. Therefor I recommend to rewrite
the UI in C#.

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
Back
Top