How to pass CString from unmanaged code to managed code?

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
 
S

Stu Smith

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;
}
 
K

Klaus Bonadt

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
 
S

Stu Smith

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.
 
S

Stu Smith

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.
 
R

Ronald Laeremans [MSFT]

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

Ronald
 

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