我有一个使用非托管 C++ 静态库的 C# 项目。当 C# 从非托管代码中取回字符串时,我遇到了一个奇怪的错误。程序崩溃,VS 告诉我可能的堆损坏。该字符串是非托管代码中对象中的一个字段 - 所以它不是局部变量问题。奇怪的是,崩溃总是在调试模式下发生,但仅在实际运行程序时的某些非常特殊的情况下才会发生。此外,尽管调试崩溃可以在所有计算机上重现,但运行时崩溃仅发生在某些计算机上。
我应该注意,我有许多从非托管代码导出的函数,除了这个函数和另一个做几乎相同事情的函数(GetBlockInfo)之外,它们都不会引起问题。
这是导致崩溃的代码行:
string info = CppToCsharpAdapter.GetFileInfo(myHashFilePointer);
CppToCsharpAdapter 是我的托管/非托管代码适配器。CppToCsharpAdapter.GetFileInfo 调用在我的非托管代码中执行对 GetFileInfo 函数的调用。
这是.cpp中的导出函数:
__declspec(dllexport) const char* __stdcall GetFileInfo(HashFile* THIS)
{
return THIS->GetFileInfo().c_str();
}
这是非托管代码中的 GetFileInfo 函数:
string& GetFileInfo()
{
try
{
LogicalHeaderBlock *infoBlock = LogicalFHBuffer;
stringstream infoString;
infoString<<infoBlock->getHashFuncID()<<endl;
// many more lines//
fileInfo = infoString.str();
return fileInfo;
}
catch(exception &e)
{ throw e; }
}
这是导致崩溃的调用堆栈:
ntdll.dll!770a04e4()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!77062a2a()
ntdll.dll!770a1b71()
oleaut32.dll!75c43e59()
[Managed to Native Transition]
mscorlib.dll!System.StubHelpers.AnsiBSTRMarshaler.ClearNative(System.IntPtr pNative) + 0x45 bytes
FMS_adapter.dll!FMS_adapter.HashFile.GetFileInfo() Line 249 + 0xb bytes C#
编辑:更新了调用堆栈,现在我得到了[Managed to Native Transition]
清楚地表明问题存在的行。
任何帮助将不胜感激。提前致谢。
编辑:我最终通过让 C# CppToCsharpAdapter.GetFileInfo() 函数返回一个 IntPtr,然后将其转换为 C# 中的字符串来解决问题。