String object to unmanged char *?

G

Guest

I have a string object that I need to convert into an unmanged char * to be
used by several unmnaged 3rd party functions.
I have tried to use: (Marshal::StringToHGlobalAuto (Profname))
This would get me an IntPtr value, but I could not find the correct way to
cast an IntPtr to an unmanged char *.
One example I tried was:
char *inifile;
inifile = static_cast <char*> (Marshal::StringToHGlobalAuto (Profname));

It gave following compile error:
c:\T02010_NET_ora9\cgi-bin\programs\TimeReader\TimeReaderWinService.cpp(236): error C2440: 'static_cast' : cannot convert from 'System::IntPtr' to 'char *'
No user-defined-conversion operator available that can perform this
conversion, or the operator cannot be called

There is another wrinkle on top of this, which I am hoping wont be a problem
once I figure the above example out. That is the parameter to function is
defined as a COMSTR which is a typedef to char far *.

The only reason profname is a string is that it is created and passed to
this function through a managed class and I could not get the managed class
to correctly keep a unmanaged char array.

Thanks,
Brian
 
G

Guest

I have tried that but it does not seem to return whole string, but only first
character in unmanaged string below is code and output from those lines

fip->WriteLine ("(profname Full Path to ini file: ]{0}[ " , Profname);

char *inifile;
char abc[200];
inifile = (char *)(Marshal::StringToHGlobalAuto (Profname)).ToPointer();
strcpy (abc, inifile);
fip->WriteLine ("inifile Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (inifile)));
fip->WriteLine ("abc Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (&abc[0])));

(profname Full Path to ini file: ]C:\WINDOWS\system32\TimeReader.ini[
inifile Full Path to ini file: ]C[
abc Full Path to ini file: ]C[
 
H

Hyd

Hello,

Personally, I use this :

String^ pmanagedString = gcnew String( "HelloWorld" );
IntPtr pstr = Marshal::StringToHGlobalAnsi( pmanagedString );
if( pstr != IntPtr::Zero )
{
char* punmanagedString =
reinterpret_cast<char*>(static_cast<void*>(pstr));
...
...
Marshal::FreeHGlobal( pstr ); // Do not forget to free the memory.
}

Hervé.

brian_harris a écrit :
I have tried that but it does not seem to return whole string, but only first
character in unmanaged string below is code and output from those lines

fip->WriteLine ("(profname Full Path to ini file: ]{0}[ " , Profname);

char *inifile;
char abc[200];
inifile = (char *)(Marshal::StringToHGlobalAuto (Profname)).ToPointer();
strcpy (abc, inifile);
fip->WriteLine ("inifile Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (inifile)));
fip->WriteLine ("abc Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (&abc[0])));

(profname Full Path to ini file: ]C:\WINDOWS\system32\TimeReader.ini[
inifile Full Path to ini file: ]C[
abc Full Path to ini file: ]C[


Mattias Sjögren said:
IntPtr::ToPointer()


Mattias
 
G

Guest

Hello,
I got the same problem using method you specified, but I did figure out what
seems to be happening, I just don't know how to fix it. It seems that the
StringToHGlobalAuto method is puting a null terminator after each character
in the String it is converting So that following code produces following
output:

fip->WriteLine ("(profname Full Path to ini file: ]{0}[ " , Profname);

char *inifile;
IntPtr pstr = Marshal::StringToHGlobalAuto (Profname);
if (pstr != IntPtr::Zero) {
inifile = reinterpret_cast<char*>(static_cast<void*>(pstr));

fip->WriteLine ("inifile Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (inifile)));
fip->WriteLine ("inifile Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (inifile+1)));
fip->WriteLine ("inifile Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (inifile+2)));
fip->WriteLine ("inifile Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (inifile+3)));
fip->WriteLine ("inifile Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (inifile+4)));
fip->WriteLine ("inifile Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (inifile+5)));
fip->WriteLine ("inifile Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (inifile+6)));
fip->WriteLine ("inifile Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (inifile+7)));
}

(profname Full Path to ini file: ]C:\WINDOWS\system32\TimeReader.ini[
inifile Full Path to ini file: ]C[
inifile Full Path to ini file: ][
inifile Full Path to ini file: ]:[
inifile Full Path to ini file: ][
inifile Full Path to ini file: ]\[
inifile Full Path to ini file: ][
inifile Full Path to ini file: ]W[
inifile Full Path to ini file: ][

Hyd said:
Hello,

Personally, I use this :

String^ pmanagedString = gcnew String( "HelloWorld" );
IntPtr pstr = Marshal::StringToHGlobalAnsi( pmanagedString );
if( pstr != IntPtr::Zero )
{
char* punmanagedString =
reinterpret_cast<char*>(static_cast<void*>(pstr));
...
...
Marshal::FreeHGlobal( pstr ); // Do not forget to free the memory.
}

Hervé.

brian_harris a écrit :
I have tried that but it does not seem to return whole string, but only first
character in unmanaged string below is code and output from those lines

fip->WriteLine ("(profname Full Path to ini file: ]{0}[ " , Profname);

char *inifile;
char abc[200];
inifile = (char *)(Marshal::StringToHGlobalAuto (Profname)).ToPointer();
strcpy (abc, inifile);
fip->WriteLine ("inifile Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (inifile)));
fip->WriteLine ("abc Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (&abc[0])));

(profname Full Path to ini file: ]C:\WINDOWS\system32\TimeReader.ini[
inifile Full Path to ini file: ]C[
abc Full Path to ini file: ]C[


Mattias Sjögren said:
This would get me an IntPtr value, but I could not find the correct way to
cast an IntPtr to an unmanged char *.

IntPtr::ToPointer()


Mattias
 
H

Hyd

Don't use StringToHGlobalAuto but StringToHGlobalAnsi : managed string
is a Unicode string and char* is a ASCII (Ansi) string.
StringToHGlobalAnsi allows to convert a string from Unicode to ASCII.

"ABC" is 41 00 42 00 43 00 00 00 (hexadecimal) in Unicode including
null terminator.
"ABC" is 41 42 43 00 (hexadecimal) in ASCII including null terminator.

Hervé.
 
G

Guest

I finally saw the big difference between what you where doing and what I was
doing. When I use StringToHGlobalAuto I get the bad results That I have
mentioned,
but if I use StringToHGlobalAnsi then it works correctly. I don't
understand what the problem is since documentation indicates that they both
should end up with same results.

Hyd said:
Hello,

Personally, I use this :

String^ pmanagedString = gcnew String( "HelloWorld" );
IntPtr pstr = Marshal::StringToHGlobalAnsi( pmanagedString );
if( pstr != IntPtr::Zero )
{
char* punmanagedString =
reinterpret_cast<char*>(static_cast<void*>(pstr));
...
...
Marshal::FreeHGlobal( pstr ); // Do not forget to free the memory.
}

Hervé.

brian_harris a écrit :
I have tried that but it does not seem to return whole string, but only first
character in unmanaged string below is code and output from those lines

fip->WriteLine ("(profname Full Path to ini file: ]{0}[ " , Profname);

char *inifile;
char abc[200];
inifile = (char *)(Marshal::StringToHGlobalAuto (Profname)).ToPointer();
strcpy (abc, inifile);
fip->WriteLine ("inifile Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (inifile)));
fip->WriteLine ("abc Full Path to ini file: ]{0}[ " ,
Marshal::ptrToStringAnsi(static_cast<IntPtr> (&abc[0])));

(profname Full Path to ini file: ]C:\WINDOWS\system32\TimeReader.ini[
inifile Full Path to ini file: ]C[
abc Full Path to ini file: ]C[


Mattias Sjögren said:
This would get me an IntPtr value, but I could not find the correct way to
cast an IntPtr to an unmanged char *.

IntPtr::ToPointer()


Mattias
 
H

Hyd

For IntPtr Marshal::StringToHGlobalAuto(string s), MSDN Library says :
"Copies the contents of a managed String into unmanaged memory,
converting into ANSI format if required".
The problem is "if required", I don't know how it can choose if it must
convert or not into ANSI. In your case, it doesn't convert into ANSI
format and char* uses ANSI format.
You can work with UNICODE format in unmanaged code, but you must use
wchar_t* string instead of char* string.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top