469,271 Members | 1,466 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,271 developers. It's quick & easy.

How to pass CString from unmanaged code to managed code?

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
Nov 17 '05 #1
7 7927
i've got the same problem, please help
--
kind regards, muechel
Nov 17 '05 #2
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;
}
"Müchel" <Mu*****@gmx.at> wrote in message
news:Oc**************@TK2MSFTNGP10.phx.gbl...
i've got the same problem, please help
--
kind regards, muechel

Nov 17 '05 #3

"Stu Smith" <st*****@remove.digita.com> schrieb im Newsbeitrag
news:uo*************@tk2msftngp13.phx.gbl...
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;
}


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

Regards,
Klaus
Nov 17 '05 #4
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.
"Klaus Bonadt" <Bo****@hotmail.com> wrote in message
news:uR**************@tk2msftngp13.phx.gbl...

"Stu Smith" <st*****@remove.digita.com> schrieb im Newsbeitrag
news:uo*************@tk2msftngp13.phx.gbl...
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;
}


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

Regards,
Klaus

Nov 17 '05 #5
Pinning and directly copying/converting to Ansi from the internal bugger of
a System::String results in only one copy. You can do this now.

E.g. See the section called "Converting Managed Strings to Character Arrays"
in
http://www.msdnaa.net/Resources/Display.aspx?ResID=1002

Ronald Laeremans
Visual C++ team

"Stu Smith" <st*****@remove.digita.com> wrote in message
news:ee**************@TK2MSFTNGP09.phx.gbl...
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.
"Klaus Bonadt" <Bo****@hotmail.com> wrote in message
news:uR**************@tk2msftngp13.phx.gbl...

"Stu Smith" <st*****@remove.digita.com> schrieb im Newsbeitrag
news:uo*************@tk2msftngp13.phx.gbl...
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;
}


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

Regards,
Klaus


Nov 17 '05 #6
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.
"Ronald Laeremans [MSFT]" <ro*****@online.microsoft.com> wrote in message
news:Od*************@TK2MSFTNGP11.phx.gbl...
Pinning and directly copying/converting to Ansi from the internal bugger of a System::String results in only one copy. You can do this now.

E.g. See the section called "Converting Managed Strings to Character Arrays" in
http://www.msdnaa.net/Resources/Display.aspx?ResID=1002

Ronald Laeremans
Visual C++ team

"Stu Smith" <st*****@remove.digita.com> wrote in message
news:ee**************@TK2MSFTNGP09.phx.gbl...
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.
"Klaus Bonadt" <Bo****@hotmail.com> wrote in message
news:uR**************@tk2msftngp13.phx.gbl...

"Stu Smith" <st*****@remove.digita.com> schrieb im Newsbeitrag
news:uo*************@tk2msftngp13.phx.gbl...
> 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;
> }

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

Regards,
Klaus



Nov 17 '05 #7
Yes, that apparently was the spell checker making the wrong change without
me catching it.

Ronald

"Stu Smith" <st*****@remove.digita.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
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.
"Ronald Laeremans [MSFT]" <ro*****@online.microsoft.com> wrote in message
news:Od*************@TK2MSFTNGP11.phx.gbl...
Pinning and directly copying/converting to Ansi from the internal bugger
of
a System::String results in only one copy. You can do this now.

E.g. See the section called "Converting Managed Strings to Character Arrays"
in
http://www.msdnaa.net/Resources/Display.aspx?ResID=1002

Ronald Laeremans
Visual C++ team

"Stu Smith" <st*****@remove.digita.com> wrote in message
news:ee**************@TK2MSFTNGP09.phx.gbl...
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.
"Klaus Bonadt" <Bo****@hotmail.com> wrote in message
news:uR**************@tk2msftngp13.phx.gbl...
>
> "Stu Smith" <st*****@remove.digita.com> schrieb im Newsbeitrag
> news:uo*************@tk2msftngp13.phx.gbl...
> > 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;
> > }
>
> It seems that this example just copies characters, i.e. using

parameter > passing by reference means copying the data twice?
>
> Regards,
> Klaus
>
>



Nov 17 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by kimberly.walker | last post: by
9 posts views Thread by =?Utf-8?B?RWR3YXJkUw==?= | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.