非托管c++代码向托管代码发送字符串的错误
Bug with Unmanaged C++ code sending a string to Managed code
我有一个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#中的字符串来解决问题。
问题在于您的CppToCsharpAdapter.GetFileInfo
的p/Invoke定义,您的问题中没有包括该定义。至少,它需要添加以下属性:
[return: MarshalAs(UnmanagedType.LPStr)]
如果省略此属性,p/Invoke层将假设返回的字符串在代码中由BSTR
表示,但实际上您使用的是以空结尾的ANSI字符串。这个链接有更多的信息:
字符串的默认封送处理:平台调用中使用的字符串
您的dll导出的GetFileInfo()
函数返回原始 const char*
,但我不确定这是托管代码的正确类型(除非您使用适当的p/Invoke签名…)。
您是否考虑过返回 BSTR
?BSTR
是一个典型的COM字符串,我认为。net非常理解COM,所以它也可以自动释放由本地代码返回的COM分配字符串。
__declspec(dllexport) BSTR __stdcall GetFileInfo(....)
{
....
// Assume that "nativeString" is "const char*".
// We first convert from ANSI/MBCS to Unicode:
// (CA2W is a conversion helper defined in <atlconv.h>)
CA2W unicodeNativeString( nativeString );
// ...and then we return a BSTR built from it:
return ::SysAllocString( unicodeNativeString );
}
编辑:
作为旁注,另一个(不是dll导出的)GetFileInfo()
函数,返回string&
,但我建议您只返回string
值(即只返回string
, 而不是 string&
)。
- C++函数的字符串错误"find_first_of"
- 流字符串错误输出
- 在图像上覆盖文本的程序会产生无休止的字符串错误
- 字符串错误的向量
- C++字数统计程序使用C字符串错误在程序运行后
- 从函数返回字符串C++错误
- 字符串错误或编译器错误
- SQL 字符串错误?没有这样的列
- C/C++ 字符串错误与 ARM SEG 故障总线错误
- 字符串错误输出
- C++调用堆上的类(空字符串错误)
- 运行时字符串错误C++
- 字符串递归函数中的字符串错误
- 从文本文件/文本流中读取Q字符串错误
- 动态内存c++程序中的字符串错误
- 发现c++正则表达式子字符串错误模式
- 在Cocos2d-x中比较字符串错误
- c++读TXT到字符串错误
- 字符串错误检查
- Chromium嵌入式框架VS2013字符串错误