passing unicode string from C# exe to C++ DLL
Using this function in my C# exe, I try to pass a Unicode string to my C++ DLL:
[DllImport("Test.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern int xSetTe开发者_运维知识库stString(StringBuilder xmlSettings);
This is the function on the C++ DLL side:
__declspec(dllexport) int xSetTestString(char* pSettingsXML);
Before calling the function in C#, I do a MessageBox.Show(string) and it displays all characters properly. On the C++ side, I do: OutputDebugStringW((wchar_t*)pString);, but that shows that the non-ASCII characters were replaced by '?'.
Just change your export in native DLL to:
extern "C" __declspec(dllexport) int xSetTestString(wchar_t* pSettingsXML);
This will do the trick.
BTW - You cant simply do char* str1 = (wchar_t*)pSettingsXML;
because it does not convert the string. You need to use wcstombs_s
to convert from wchar_t*
to char*
. But in your case you don't have to do it.
Notes: Best practice IMO is to use TCHAR*
instead of wchar_t*
directly, and set your native dll project General option Character Set to Use Unicode Character Set. This defines TCHAR*
as wchar_t*
.
Mirosoft natively uses two sets of functions: ANSI, using 1-byte chracter, marked as FunctionNameA and Unicode, using 2-bytes character, marked as FunctionNameW. This Unicode is in fact UTF-16.
UTF-8 is a multi-byte string that uses 1-byte for standard character and 2-bytes for non-standard characters. To convert UTF-8 to UTF-16 you can use MultiByteToWideChar
function.
Try:
[DllImport("Test.dll")]
[return : MarshalAs(UnmanagedType.I4)]
private static extern int externalTestString(
[MarshalAs(UnmanagedType. // The string type the C uses ansi/unicode/...) ] String st
);
public int TestString(String st // or string builder here)
{
// Perform input/output checks here + exception handling
}
Make sure the C++ functions are visible outside the DLL (using __declspec dllexport). Check using depends (comes with VS2005) if you can see the functions and what there name is.
If your C++ functions are NOT within classes, then you can use unmangled names if you use extern "C", if they are in classes, you will need to specify an entry point with the mangled names from depends.
精彩评论