我试图制作某种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 *直接传递给构造函数,但这也没有用。我在这里找不到什么东西?
答案 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)