Conversion problem
-
Hello all, Does anyone know how to convert System::String to C++ language char * ? I found a few functions but it convert to wchar_t which is not what i want. Any hints? Secondly, i have a unmanaged c++ function in which prototype in such. BOOL MImImage::Combine(MImImage *pImImage); why is that the parameter appear as class NamespaceXX.MImImage in ILDASM? I want a pointer parameter so that i could pass in an array of MImImage. Thanks in advance.
-
Hello all, Does anyone know how to convert System::String to C++ language char * ? I found a few functions but it convert to wchar_t which is not what i want. Any hints? Secondly, i have a unmanaged c++ function in which prototype in such. BOOL MImImage::Combine(MImImage *pImImage); why is that the parameter appear as class NamespaceXX.MImImage in ILDASM? I want a pointer parameter so that i could pass in an array of MImImage. Thanks in advance.
If you haven't already, you can use Marshal::StringToHGlobalAnsi() in the System::Runtime::InteropServices namespace. That will allocate to regular heap which needs to be freed by calling FreeHGlobal(). If you want to copy the bytes to your own memory space/buffer, you can do it with a little extra work. First, pin the String on the GC heap (tell the GC not to move it), and then convert like any wchar_t array. Roughly, given CLR String "Str":
inline wchar_t * PtrToStringArray(System::String *s) { System::String __pin*pps = s; //pin to avoid 1-instruction GC hole in reinterpret_cast System::Byte __pin*bp = reinterpret_cast(s); if( bp != 0 ) bp += System::Runtime::CompilerServices::RuntimeHelpers::OffsetToStringData; return reinterpret_cast(bp); }; wchar_t *pStr = PtrToStringArray(Str); //pin and access array int iChrs = WideCharToMultiByte(CP_ACP, 0, pStr, Str->Length, pYourBuf, iBufLen, NULL, NULL); //do whatever with ANSI string in pYourBuf
PtrToStringArray() is my version of PtrToStringData() from vcclr.h, which keeps a String pinned, and gets a pointer to its internal wchar_t array. I use it often in MC++ wrappers. The pinning will release when the block that contains PtrToStringArray() exits. As to your second question, all __gc objects are passed around as pointers, and there is no assumption about pointers possibly being to an array of objects. To do so, you need to declare the param as a gc array:BOOL MImImage::Combine(MImImage *ImImageArray __gc[]);
The CLR has a strange syntax for declaring arrays, but that's it. Cheers -
If you haven't already, you can use Marshal::StringToHGlobalAnsi() in the System::Runtime::InteropServices namespace. That will allocate to regular heap which needs to be freed by calling FreeHGlobal(). If you want to copy the bytes to your own memory space/buffer, you can do it with a little extra work. First, pin the String on the GC heap (tell the GC not to move it), and then convert like any wchar_t array. Roughly, given CLR String "Str":
inline wchar_t * PtrToStringArray(System::String *s) { System::String __pin*pps = s; //pin to avoid 1-instruction GC hole in reinterpret_cast System::Byte __pin*bp = reinterpret_cast(s); if( bp != 0 ) bp += System::Runtime::CompilerServices::RuntimeHelpers::OffsetToStringData; return reinterpret_cast(bp); }; wchar_t *pStr = PtrToStringArray(Str); //pin and access array int iChrs = WideCharToMultiByte(CP_ACP, 0, pStr, Str->Length, pYourBuf, iBufLen, NULL, NULL); //do whatever with ANSI string in pYourBuf
PtrToStringArray() is my version of PtrToStringData() from vcclr.h, which keeps a String pinned, and gets a pointer to its internal wchar_t array. I use it often in MC++ wrappers. The pinning will release when the block that contains PtrToStringArray() exits. As to your second question, all __gc objects are passed around as pointers, and there is no assumption about pointers possibly being to an array of objects. To do so, you need to declare the param as a gc array:BOOL MImImage::Combine(MImImage *ImImageArray __gc[]);
The CLR has a strange syntax for declaring arrays, but that's it. CheersThanx. Your reply really comes in at a good time. :-)
-
Thanx. Your reply really comes in at a good time. :-)
My pleasure. However, I forgot there were embedded < and > characters in my last post, so the code was clipped. Here is the correct code displayed as non-HTML: inline wchar_t * PtrToStringArray(System::String *s) { System::String __pin*pps = s; //pin to avoid 1-instruction GC hole in reinterpret_cast System::Byte __pin*bp = reinterpret_cast(s); if( bp != 0 ) bp += System::Runtime::CompilerServices::RuntimeHelpers::OffsetToStringData; return reinterpret_cast(bp); }; wchar_t *pStr = PtrToStringArray(Str); //pin and access array int iChrs = WideCharToMultiByte(CP_ACP, 0, pStr, Str->Length, pYourBuf, iBufLen, NULL, NULL); //do whatever with ANSI string in pYourBuf Cheers