I've spent a great deal
of time tying figuring out how to pass c#
strings to an unmanaged c++ program. Therefore, here is a little what I
discovered how it can be done.
C# strings don't work
the same as c++ strings. In C++ a string is referenced by a pointer -
something C# does not do. In C#, types are either value types or
reference types (placed on the heap) and aren't accessible as they are
in unmanaged space.
Suppose you want to
call a method that was written in C++ that takes in string values of
type LPCWSTR.
You add C++ Class Library DLL to your project.
For example, here's the C++ part it:
void PassStrings(LPCWSTR string1,LPCWSTR string2)
{...}
Now, you want to call this from
C#.
Simply doing this: PassStrings(s1, s1) where s1 and s2 are string types
won't work.
It turns out (at least what I discovered) there is a way by using the
"StringToHGlobalUni" method, and converting it to a Pointer using
ToPointer(). Be sure to add
using System.Runtime.InteropServices;
unsafe{
char* a1 = (char *)Marshal.StringToHGlobalUni(s1).ToPointer();
char* a2 = (char *)Marshal.StringToHGlobalUni(s2).ToPointer();
classobj.PassStrings(a1, a2);
}Also use the
"unsafe" keyword
along with the unsafe compiler option.
This at least works for LPCWSTR types. For char*
or String^ types will probably
need some modifications.
The code below taken from support.microsoft.com shows some methods done on the c++ side:
//compiler option: cl /clr
#include <vcclr.h>
#include <atlstr.h>
#include <stdio.h>
#using <mscorlib.dll>
using namespace System;
using namespace System::Runtime::InteropServices;
int _tmain(void)
{
System::String * str = S"Hello world\n";
//method 1
const __wchar_t __pin * str1 = PtrToStringChars(str);
wprintf(str1);
//method 2
char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
printf(str2);
Marshal::FreeHGlobal(str2);
//method 3
CString str3(str); ntf(str3);
return 0;
}
By
Frank Neubecker