用dllexport传递std :: string

时间:2018-03-08 17:28:21

标签: c++ interop dllimport

我试图制作某种C ++" bridge"将一个非托管C ++ DLL连接到一端(不修改它们的代码)到C#Wrapper,它使用DllImport进行各种导入。

我能够使用char指针将C#字符串传递给我的桥接器,但接收Dll需要接收std :: string,所以我尝试使用//check top if (n[i][j] == blank) { if (i - 1 >= 0) { if (n[i - 1][j] == enemyPiece) { for (int a = i - 2; a >= 0; a--) { if (n[a][j] == ourPiece) { possibleMovesList[0].push_back(i); possibleMovesList[1].push_back(j); possibleMovesList[2].push_back(2); out << "Yes -> Case 2" << " r = " << a << " c = " << j << endl; break; } if (n[a][j] == blank) { break; } } } } } 没有运气,它总是被转换成奇怪的字符

结构如下:

C#Wrapper

std::string(foo);

C ++ Bridge

[DllImport(@"Bridge.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void initDetector(string foo, int something = 0);

C ++导入的DLL(此处不允许更改代码)

extern "C" __declspec(dllexport) void initCppClass(char* foo, int something)
{
    std::string bar = std::string(foo);
    std::cout << bar << std::endl; //Returns "foo"
    instance = new CppClass(bar, something);
}

请注意,此构造函数仅用于演示目的,因为我无法透露原始代码。

我最初尝试将char *直接传递给构造函数,但这也没有用。我在这里找不到什么东西?

1 个答案:

答案 0 :(得分:0)

我认为问题是不同的字符串编码。

尝试在C#中添加CharSet = CharSet.Ansi,如下所示:

[DllImport(@"Bridge.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]

但是,请阅读该C ++ DLL API的文档。许多C ++代码,特别是如果是跨平台代码,期望UTF8编码的字符串。如果是你的情况,而是将桥梁改为

extern "C" __declspec(dllexport) void initCppClass(const wchar_t* foo, int something)

编写代码以将字符串从UTF16编码的C指针转换为UTF8编码的std :: string,有关示例,请参阅this answer

更新:另一个可能的原因是不同的STL或不同的CRT。当您跨DLL边界传递std :: string或任何其他STL对象对象时,您必须使用相同的编译器和放大器。相同版本的,相同的构建设置(例如在VC ++中,std :: strings内存布局在调试和发布版本之间不同),并且两个DLL也必须动态地链接到CRT。 Multi-threaded DLL (/MD)