如何从Native(C++)代码返回文本

Jam*_*ame 33 c# c++ string pinvoke

我使用Pinvoke实现本机(C++)代码和托管(C#)代码之间的互操作性.我想要实现的是从本机代码中获取一些文本到我的托管代码中.为此,我尝试了很多东西,例如通过ref传递字符串/ stringbuilder,使用[IN]和[OUT],Marshaling到LPSTR,从函数返回字符串等,但在我的情况下没有任何作用.任何有关一些小代码的帮助都将受到高度赞赏.

Dav*_*nan 47

我这样做是BSTR因为它意味着你不必每个字符串调用两次,一次获取长度然后一次获取内容.

使用BSTRmarshaller将负责BSTR使用正确的内存管理器解除分配,以便您可以安全地将其从C++代码中传出.

C++

#include <comutil.h>
BSTR GetSomeText()
{
    return ::SysAllocString(L"Greetings from the native world!");
}
Run Code Online (Sandbox Code Playgroud)

C#

[DllImport(@"test.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string GetSomeText();
Run Code Online (Sandbox Code Playgroud)

有一个小缺点BSTR,即它带有UTF-16有效载荷,但你的源数据可能很好char*.

要解决这个问题,您可以将转换结束char*BSTR:

BSTR ANSItoBSTR(const char* input)
{
    BSTR result = NULL;
    int lenA = lstrlenA(input);
    int lenW = ::MultiByteToWideChar(CP_ACP, 0, input, lenA, NULL, 0);
    if (lenW > 0)
    {
        result = ::SysAllocStringLen(0, lenW);
        ::MultiByteToWideChar(CP_ACP, 0, input, lenA, result, lenW);
    } 
    return result;
}
Run Code Online (Sandbox Code Playgroud)

这是方式的最难的了,现在可以很容易地添加其他包装转换到BSTRLPWSTR,std::string,std::wstring等.


Dis*_*ser 5

是一个讨论过字符串封送处理的主题。

需要用属性标记参数

[MarshalAs(UnmanagedType.LPSTR)]
Run Code Online (Sandbox Code Playgroud)