在我的C#exe中使用此函数,我尝试将Unicode字符串传递给我的C ++ DLL:
[DllImport("Test.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern int xSetTestString(StringBuilder xmlSettings);
这是C ++ DLL端的功能:
__ declspec(dllexport)int xSetTestString(char * pSettingsXML);
在C#中调用函数之前,我执行MessageBox.Show(string)并正确显示所有字符。在C ++方面,我这样做:OutputDebugStringW((wchar_t *)pString);,但是这表明非ASCII字符被'?'取代。
答案 0 :(得分:5)
只需将原生DLL中的导出更改为:
extern "C" __declspec(dllexport) int xSetTestString(wchar_t* pSettingsXML);
这样就可以了。
BTW - 您不能简单地执行char* str1 = (wchar_t*)pSettingsXML;
因为它不会转换字符串。您需要使用wcstombs_s
将wchar_t*
转换为char*
。但在你的情况下,你不必这样做。
注意:最佳做法IMO将直接使用TCHAR*
而不是wchar_t*
,并设置您的原生dll项目常规选项字符集到使用Unicode字符集。这将TCHAR*
定义为wchar_t*
。
Mirosoft本身使用两组函数:ANSI,使用1字节字符,标记为FunctionNameA和Unicode,使用2字节字符,标记为FunctionNameW。这个Unicode实际上是UTF-16。
UTF-8是一个多字节字符串,对于标准字符使用1字节,对非标准字符使用2字节。要将UTF-8转换为UTF-16,您可以使用MultiByteToWideChar
函数。
答案 1 :(得分:0)
尝试:
[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
}
确保C ++函数在DLL外部可见(使用__declspec dllexport)。 如果您可以看到函数及其名称,请使用depends(自带VS2005)进行检查。
如果您的C ++函数不在类中,那么如果使用extern“C”,则可以使用未编码的名称,如果它们在类中,则需要指定一个带有来自depends的错位名称的入口点。