pinvoke字符串中只传递第一个字符 我有一个C++的DLL,我使用p援克.< /p>

pinvoke字符串中只传递第一个字符 我有一个C++的DLL,我使用p援克.< /p>,dll,pinvoke,dllimport,Dll,Pinvoke,Dllimport,方法签名如下: c++: C#: 出于技术原因,我用一个库替换了dll,并用一个使用EXPORTS.def文件和EXPORTS声明从库导出方法的dll包装了该库。 因为我吃过饭,所以我看到一种奇怪的行为。我只获取第一个字符,而不是在方法实现中获取字符串 我曾试图替换调用约定,使用MalSalas LPCWSTR,并且试图用Car *替换C++解密中的LPCSTR。 以上这些都帮助我解决了这个问题,我仍然只得到了第一个字符 发生这种情况的原因以及如何解决此问题?LPCSTR是指向以null结尾的字

方法签名如下:

c++:

C#:

出于技术原因,我用一个库替换了dll,并用一个使用EXPORTS.def文件和EXPORTS声明从库导出方法的dll包装了该库。 因为我吃过饭,所以我看到一种奇怪的行为。我只获取第一个字符,而不是在方法实现中获取字符串

我曾试图替换调用约定,使用MalSalas LPCWSTR,并且试图用Car *替换C++解密中的LPCSTR。 以上这些都帮助我解决了这个问题,我仍然只得到了第一个字符


发生这种情况的原因以及如何解决此问题?

LPCSTR
是指向以null结尾的字符数组和非托管类型的指针。LPWStr是指向以null结尾的字符数组的指针。所以有一个简单的错误匹配

仅接收单个字符的原因是,当ASCII字符表示为两字节UTF-16字符时,一个字节中包含ASCII值,另一个字节中包含零。当解释为以null结尾的字符数组时,这是一个长度为1的字符串。零字节被解释为空终止符

您可以通过更改以下任一项来修复它:

  • LPCSTR
    到本机端的
    LPCWSTR
    ,或
  • UnmanagedType.LPWStr
    到托管端的
    UnmanagedType.LPStr
  • 坦白地说,对我来说,现在使用Unicode更有意义,所以我会选择选项1。实际上,由于您指定了
    CharSet.Unicode
    ,因此根本不需要
    MarshalAs
    。代码如下所示:

    C++

    BOOL std_call MyCppMethod(LPCWSTR param1, LPCWSTR param2);
    
    C#


    请注意,我也怀疑您将
    SetLastError
    设置为
    true
    。您的函数真的调用了
    SetLastError

    您的字符集完全错误。LPCSTR需要CharSet.AnsiThanks。我刚刚弄明白:)但是你能想出一个原因吗?当它是一个dll而不是一个库时,它没有失败?是的,你是对的,当我将LPCSTR更改为std::string并在调试器中看到每秒钟的字节都是“0”时,我就明白了这一点。我仍然觉得奇怪的是,当我有一个.dll而不是一个用.dll包装的lib时,同样的代码可以工作。这有可能吗?不,不可能。我想没有。可能工作的版本有不同的代码。
    [DllImport("MyDll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern bool MyCppMethod(
             /*[MarshalAs(UnmanagedType.LPWStr)]*/ string param1,
             /*[MarshalAs(UnmanagedType.LPWStr)]*/ string param2
            );
    
    BOOL std_call MyCppMethod(LPCWSTR param1, LPCWSTR param2);
    
    [DllImport("MyDll.dll", CharSet = CharSet.Unicode)]
    public static extern bool MyCppMethod(string param1, string param2);