Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / March 2005

Tip: Looking for answers? Try searching our database.

Dumb String Conversion Problem?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Fred Hebert - 29 Mar 2005 00:10 GMT
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());
Jochen Kalmbach - 29 Mar 2005 10:00 GMT
> 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>

Signature

Greetings
  Jochen

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

Peteroid - 29 Mar 2005 10:09 GMT
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==]

>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
[quoted text clipped - 4 lines]
> ...
> TheFunc(Junk->Text->Something());
Jochen Kalmbach - 29 Mar 2005 10:17 GMT
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.

Signature

Greetings
  Jochen

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

Jochen Kalmbach - 29 Mar 2005 10:09 GMT
> 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
[quoted text clipped - 4 lines]
> ...
> TheFunc(Junk->Text->Something());

The easiest way is to use the CString-Class:

<code>
#include <afx.h>

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

Signature

Greetings
  Jochen

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

Fred Hebert - 29 Mar 2005 16:38 GMT
>> 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
[quoted text clipped - 12 lines]
> 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?
Jochen Kalmbach - 29 Mar 2005 18:25 GMT
Hi Fred!
>>>I have a function that requires a LPCTSTR parameter.
> 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>
#include <stdio.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...

Signature

Greetings
  Jochen

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

Fred Hebert - 29 Mar 2005 21:00 GMT
> Hi Fred!
>>>>I have a function that requires a LPCTSTR parameter.
[quoted text clipped - 23 lines]
>
> 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.
Jochen Kalmbach - 30 Mar 2005 07:41 GMT
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
[quoted text clipped - 5 lines]
> 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#.

Signature

Greetings
  Jochen

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


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.