How to pass CString from unmanaged code to managed code?

  • Thread starter Thread starter Klaus Bonadt
  • Start date Start date
K

Klaus Bonadt

I have an existing VC6 application using the MFC.
I am able to pass CString and other parameters from such a VC6 dll to an
unmanaged MFC dll (compiled in Visual Studio .NET).
Now I want to use .Net functionality, i.e. calling methods in managed code.
How do I pass CString variables for input and output usage, i.e. providing
and retrieving char arrays?

Regards,
Klaus
 
For unmanaged to managed, I was under the impression that MC++ would
automatically marshall char * to System.String. I suppose you might need to
use .c_str() to get that. "IJW", as far as I can remember.

For going managed to unmanaged, you need to allocate space for the string,
you ccould try a function like this:

inline CString ToStr( System::String *strParam )
{
using System::Runtime::InteropServices::Marshal;
System::IntPtr ptr = Marshal::StringToHGlobalAnsi( strParam );
CString str = static_cast<LPCTSTR>( const_cast<void*>(static_cast<const
void*>( ptr ) ) );
Marshal::FreeHGlobal( ptr );
return str;
}
 
Stu Smith said:
For unmanaged to managed, I was under the impression that MC++ would
automatically marshall char * to System.String. I suppose you might need to
use .c_str() to get that. "IJW", as far as I can remember.

For going managed to unmanaged, you need to allocate space for the string,
you ccould try a function like this:

inline CString ToStr( System::String *strParam )
{
using System::Runtime::InteropServices::Marshal;
System::IntPtr ptr = Marshal::StringToHGlobalAnsi( strParam );
CString str = static_cast<LPCTSTR>(
const_cast said:
void*>( ptr ) ) );
Marshal::FreeHGlobal( ptr );
return str;
}

It seems that this example just copies characters, i.e. using parameter
passing by reference means copying the data twice?

Regards,
Klaus
 
Yes, to go from managed to unmanaged you have to copy the string; you
certainly can't get a pointer to managed memory as the object might (will)
move. The only safe thing you can do is copy the string.

As for copying the data twice, well System::String doesn't specify how it
stores the characters (ie it can store them internally how it likes). You've
got two real options for getting a sequence of chars out; one is to use the
ToCharArray method (probably involves copying) and the other is to use one
of the marshall methods.

If you got the managed char array you could pin it and then copy it to a
CString, but that's two copies. If you use Marshall you can get an unmanaged
string but if you want it wrapped as a CString you have to do another copy.

I guess Microsoft could write a single-copy marshall routine that goes
straight to a CString if they wanted to.

If anyone does know a better method of marshalling strings from managed to
unmanaged I'd be happy to be enlightened as we use the double-copy code
below.
 
Well I am now enlightened. I didn't know you could access the internal
'bugger' but you learn something everyday.

I'll have an experiment with that once we're out of code-freeze.

Thanks.
 
Yes, that apparently was the spell checker making the wrong change without
me catching it.

Ronald
 
Back
Top