我有一个使用Pinvoke的c ++ dll。
方法签名如下:
C ++:
EXTERN_C BOOL std_call MyCppMethod(LPCSTR param1, LPCSTR param2);
C#:
[DllImport("MyDll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool MyCppMethod(
/*[MarshalAs(UnmanagedType.LPWStr)]*/ string param1,
/*[MarshalAs(UnmanagedType.LPWStr)]*/ string param2
);
由于技术原因我用lib替换了dll,并用一个使用EXPORTS.def文件和EXPORTS声明的DLL包装lib来从lib导出方法。 因为我吃饭,所以我看到了一种奇怪的行为。而不是在方法实现中获取字符串,我只得到第一个字符。
我曾尝试替换调用约定,使用marshal作为LPCWSTR,并尝试用char *替换c ++ decleration中的lpcstr。 以上没有帮助我解决问题,我仍然只得到第一个字符。
为什么会这样,我该如何解决这个问题?
答案 0 :(得分:2)
LPCSTR
是指向以空值终止的char
数组的指针,UnmanagedType.LPWStr
是指向以wchar_t
为空的数组的指针。所以有一个简单的不匹配。
您只收到单个字符的原因是ASCII字符在表示为两个字节的UTF-16字符时,在一个字节中具有ASCII值,在另一个字节中具有零值。当解释为char
的以空值终止的数组时,这是一个长度为1的字符串。零字节被解释为空终止符。
您可以通过更改:
来修复它LPCSTR
到LPCWSTR
,或UnmanagedType.LPWStr
至UnmanagedType.LPStr
。坦率地说,对我而言,最近使用Unicode更有意义,所以我会选择选项1.事实上,由于您指定了CharSet.Unicode
,因此根本不需要MarshalAs
。代码如下所示:
<强> C ++ 强>
BOOL std_call MyCppMethod(LPCWSTR param1, LPCWSTR param2);
<强> C#强>
[DllImport("MyDll.dll", CharSet = CharSet.Unicode)]
public static extern bool MyCppMethod(string param1, string param2);
请注意,我对您SetLastError
到true
的设置持怀疑态度。你的功能真的叫SetLastError
吗?