只有第一个字符在pinvoke字符串中传递

时间:2014-03-19 10:19:29

标签: dll pinvoke dllimport

我有一个使用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。 以上没有帮助我解决问题,我仍然只得到第一个字符。

为什么会这样,我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

LPCSTR是指向以空值终止的char数组的指针,UnmanagedType.LPWStr是指向以wchar_t为空的数组的指针。所以有一个简单的不匹配。

您只收到单个字符的原因是ASCII字符在表示为两个字节的UTF-16字符时,在一个字节中具有ASCII值,在另一个字节中具有零值。当解释为char的以空值终止的数组时,这是一个长度为1的字符串。零字节被解释为空终止符。

您可以通过更改:

来修复它
    本机上的
  1. LPCSTRLPCWSTR,或
  2. 管理方
  3. UnmanagedType.LPWStrUnmanagedType.LPStr
  4. 坦率地说,对我而言,最近使用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);
    

    请注意,我对您SetLastErrortrue的设置持怀疑态度。你的功能真的叫SetLastError吗?