【发布时间】:2017-11-20 23:36:47
【问题描述】:
我有一个本地 C++ dll,我从托管 c++ dll 调用它,而托管 c++ dll 从 C# 应用程序调用。
本机 dll 中的函数如下所示:
std::string NativeClass::Test()
{
return std::string("some string");
}
调用它的托管 C++ 函数看起来像这样
String ^ ManagedClass::Test()
{
std::string temp = this->_native->Test();
String^ sRet = msclr::interop::marshal_as<String^>(temp);
return sRet; // crashes here !!!
}
但是,在执行 return 语句时,应用程序崩溃并出现类似的错误
Debug Assertion Failed!
debug_heap.cpp
Line 980
Expression: __acrt_first_block == header
我查看了整个 Stackoverflow,但我还没有解决它。有什么想法吗?
【问题讨论】:
-
如果您尝试在 return 语句之前使用任何一个字符串会发生什么?您能否添加非托管字符串的 printf 和托管字符串的 Debug.WriteLine,让我们知道会发生什么?
-
非托管字符串写出“some string”,托管字符串写出“some string”
-
标准 C++ 库类型(如 std::string)在被分配到一个 DLL 并在另一个 DLL 中销毁时,通常会表现得很糟糕。使用完全相同版本的 CRT 创建和销毁对象至关重要。请务必使用完全相同的设置(减去 /clr)使用完全相同的编译器版本重建该原生 DLL,需要 /MD。
-
@Tim49 尝试通过
String^ sRet = gcnew String(temp.c_str());封送std::string。这是MSDN 建议的另一种方法。 -
不要专注于编组,那不是失败的原因。爆炸的是 std::string 析构函数。 temp 对象在其作用域块的末尾被销毁,使它看起来像是失败的 return 语句。
标签: c++ c++-cli marshalling