2014-03-19 68 views
1

我有一个C++ dll,我正在使用Pinvoke。只有第一个字符在pinvoke字符串中传递

方法签名为如下:

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,并且包裹的lib与dll使用EXPORTS.def文件和EXPORTS声明从lib中导出方法。 因为我吃饭,我看到一个奇怪的行为。而不是在方法实现中获取字符串,我只获得第一个字符。

我曾尝试替换调用约定,使用marshalAs LPCWSTR,并试图用char *替换C++ decleration中的lpcstr。 非上述帮助我解决了这个问题,我仍然只获得第一个字符。

为什么会发生这种情况,我该如何解决这个问题?

+1

你的CharSet是完全错误的。 LPCSTR要求CharSet.Ansi –

+0

谢谢。我刚刚弄明白了:)但你能想到它的原因为什么它没有失败,当它是一个DLL而不是一个库? – user844541

回答

2

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

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

  1. LPCSTRLPCWSTR在本机端,或
  2. UnmanagedType.LPWStrUnmanagedType.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); 

请注意,我也怀疑你的设置SetLastErrortrue。你的功能真的叫SetLastError

+0

是的,你说得对,当我将LPCSTR更改为std :: string并在调试器中看到每个第二个字节都为'0'时,我想到了这一点。我仍然感到奇怪的是,当我有.dll而不是用.dll包装的lib时,相同的确切代码有效吗? – user844541

+0

不,这是不可能的 –

+0

所以它可能从来没有工作过:( – user844541

相关问题