I use the following code to convert a managed string to an unmanaged one:

_TCHAR error[255];
const char* umstring = (const char*)Marshal::StringToHGlobalAnsi
(merror).ToPointer();
_tcscpy(error, umstring);
Marshal::FreeHGlobal(IntPtr((void*)umstring));

I can't use StringToHGlobalAuto because it only ever returns the first
character.
I asked why a bit ago, and somebody said you can't use StringToHGlobalAuto
because of something I can't remember, but in any case it doesn't work so
don't say that.
But they also said I need to put my own unicode checking around that, but I
can't see what the point would be - as aren't all managed strings unicode
anyway?
This leads me to believe it must be doing whatever conversions for me I
require anyway.
Is it?
If not, what is the required unicode checking?

Re: managed string -> unmanaged string by Jochen

Jochen
Mon Oct 18 06:52:46 CDT 2004

=?Utf-8?B?Qm9uag==?= wrote:

> I use the following code to convert a managed string to an unmanaged
> one:

In general: For string conversion see:
HOW TO: Convert from System::String* to Char* in Visual C++ .NET
http://support.microsoft.com/kb/311259/


> _TCHAR error[255];
> const char* umstring = (const char*)Marshal::StringToHGlobalAnsi
> (merror).ToPointer();
> _tcscpy(error, umstring);
> Marshal::FreeHGlobal(IntPtr((void*)umstring));

This works *only* if you have an ANSI/MBCS project!
If your projects is compiled with _UNICODE/UNICODE then it will not work!

To support TCHAR you have to do:

<code>
//#include <vcclr.h>

System::String * merror = S"Hello world";
_TCHAR error[255];
#ifdef _UNICODE
const __wchar_t __pin * umstring = PtrToStringChars(merror);
#else
const char* umstring = (const char*)Marshal::StringToHGlobalAnsi
(error).ToPointer();
#endif
_tcscpy(error, umstring);
#ifndef _UNICODE
Marshal::FreeHGlobal(IntPtr((void*)umstring));
#endif
</code>

You should also check the string length!!!!

--
Greetings
Jochen

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

Re: managed string -> unmanaged string by Bonj

Bonj
Mon Oct 18 07:09:12 CDT 2004

Thanks very much for the example, it looks rockin'.
Just one question. What does "__pin" do?


"Jochen Kalmbach" wrote:

> =?Utf-8?B?Qm9uag==?= wrote:
>
> > I use the following code to convert a managed string to an unmanaged
> > one:
>
> In general: For string conversion see:
> HOW TO: Convert from System::String* to Char* in Visual C++ .NET
> http://support.microsoft.com/kb/311259/
>
>
> > _TCHAR error[255];
> > const char* umstring = (const char*)Marshal::StringToHGlobalAnsi
> > (merror).ToPointer();
> > _tcscpy(error, umstring);
> > Marshal::FreeHGlobal(IntPtr((void*)umstring));
>
> This works *only* if you have an ANSI/MBCS project!
> If your projects is compiled with _UNICODE/UNICODE then it will not work!
>
> To support TCHAR you have to do:
>
> <code>
> //#include <vcclr.h>
>
> System::String * merror = S"Hello world";
> _TCHAR error[255];
> #ifdef _UNICODE
> const __wchar_t __pin * umstring = PtrToStringChars(merror);
> #else
> const char* umstring = (const char*)Marshal::StringToHGlobalAnsi
> (error).ToPointer();
> #endif
> _tcscpy(error, umstring);
> #ifndef _UNICODE
> Marshal::FreeHGlobal(IntPtr((void*)umstring));
> #endif
> </code>
>
> You should also check the string length!!!!
>
> --
> Greetings
> Jochen
>
> My blog about Win32 and .NET
> http://blog.kalmbachnet.de/
>

Re: managed string -> unmanaged string by Jochen

Jochen
Mon Oct 18 07:12:34 CDT 2004

> You should also check the string length!!!!

See: Convert from System::String* to TCHAR
http://blog.kalmbachnet.de/?postid=18

--
Greetings
Jochen

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

Re: managed string -> unmanaged string by Jochen

Jochen
Mon Oct 18 07:13:44 CDT 2004

=?Utf-8?B?Qm9uag==?= wrote:

> Thanks very much for the example, it looks rockin'.
> Just one question. What does "__pin" do?

It prevents the pointer from GC.

--
Greetings
Jochen

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

Re: managed string -> unmanaged string by Tomas

Tomas
Mon Oct 18 08:05:48 CDT 2004

Jochen,

> > Thanks very much for the example, it looks rockin'.
> > Just one question. What does "__pin" do?
>
> It prevents the pointer from GC.

Actually, it prevents the GC from _moving_ the object pointed to by the
__pin pointer, which is slighly different.

--
Tomas Restrepo
tomasr@mvps.org



Re: managed string -> unmanaged string by Bonj

Bonj
Mon Oct 18 13:59:50 CDT 2004

but it won't delete it using one of its own threads though either, no?

"Tomas Restrepo (MVP)" <tomasr@mvps.org> wrote in message
news:udSl2MRtEHA.3412@TK2MSFTNGP14.phx.gbl...
> Jochen,
>
>> > Thanks very much for the example, it looks rockin'.
>> > Just one question. What does "__pin" do?
>>
>> It prevents the pointer from GC.
>
> Actually, it prevents the GC from _moving_ the object pointed to by the
> __pin pointer, which is slighly different.
>
> --
> Tomas Restrepo
> tomasr@mvps.org
>
>



Re: managed string -> unmanaged string by Tomas

Tomas
Mon Oct 18 18:05:04 CDT 2004

Bonj,

> but it won't delete it using one of its own threads though either, no?

That's a different thing altogether... it's not the presence of the pinning
pointer that prevents garbage collection, per se, but the fact that the
object is reachable through some reference to it. In this case, the pointer
you created the pinning pointer from should suffice.

In other words, we're talking two different things here: you don't usually
pin a pointer to prevent it from getting GC'd, you pin it to prevent it from
being *moved*.

Quite different, really.

--
Tomas Restrepo
tomasr@mvps.org



Re: managed string -> unmanaged string by Bonj

Bonj
Tue Oct 19 00:49:24 CDT 2004

Right, so it doesn't matter what happens to the pointer, as long as the data
it points to is still there, but if the data gets moved, doom...
And that's what the garbage collector does isn't it.
But when the GC 'moves' a managed object legitimately, does it update the
pointer to point to the new location? Presumably this is transparent
normally in .NET but it can't happen with unmanaged pointers?

Cheers


"Tomas Restrepo (MVP)" <tomasr@mvps.org> wrote in message
news:umwtzbWtEHA.3016@TK2MSFTNGP12.phx.gbl...
> Bonj,
>
>> but it won't delete it using one of its own threads though either, no?
>
> That's a different thing altogether... it's not the presence of the
> pinning
> pointer that prevents garbage collection, per se, but the fact that the
> object is reachable through some reference to it. In this case, the
> pointer
> you created the pinning pointer from should suffice.
>
> In other words, we're talking two different things here: you don't usually
> pin a pointer to prevent it from getting GC'd, you pin it to prevent it
> from
> being *moved*.
>
> Quite different, really.
>
> --
> Tomas Restrepo
> tomasr@mvps.org
>
>



Re: managed string -> unmanaged string by Tomas

Tomas
Tue Oct 19 06:06:13 CDT 2004

Bonj,

> Right, so it doesn't matter what happens to the pointer, as long as the
data
> it points to is still there, but if the data gets moved, doom...
> And that's what the garbage collector does isn't it.

It does both... move them, and remove them

> But when the GC 'moves' a managed object legitimately, does it update the
> pointer to point to the new location?

Only managed handles in places that are under the GC control (i.e the
managed heap, or the managed stack). It won't update pointers in places it
it can't control (like in the CRT heap, etc.)
That's the reason to have pinning pointers: ensuring the gc doesn't move the
object referenced in memory, so that the pointers you pass to it to
unmanaged code remain valid...

--
Tomas Restrepo
tomasr@mvps.org



Re: managed string -> unmanaged string by adebaene

adebaene
Tue Oct 19 07:28:49 CDT 2004

"Bonj" <benjtaylor at hotpop d0t com> wrote in message news:<#Ca0Y9ZtEHA.3200@TK2MSFTNGP09.phx.gbl>...
> Right, so it doesn't matter what happens to the pointer, as long as the data
> it points to is still there, but if the data gets moved, doom...
> And that's what the garbage collector does isn't it.
Yes, after having deleted unreferneced objects, the GC compacts the
heap by moving all the remaining objects in contiguous space.

> But when the GC 'moves' a managed object legitimately, does it update the
> pointer to point to the new location?
It doesn't update pointers, it updates managed references (or
handles). In managed C++, those handles are represented by "managed
pointers".

> Presumably this is transparent
> normally in .NET but it can't happen with unmanaged pointers?
Yes, that's the whole point of pinning pointers : temporaly prevent
the GC to move an object, so that unmanaged code can use the memory
without risk of access violation.

Arnaud
MVP - VC