我在C#中使用非託管C++靜態庫的項目。當C#從非託管代碼中取回字符串時,我遇到了一個奇怪的錯誤。該程序崩潰,VS告訴我可能的堆損壞。該字符串是非託管代碼中對象的字段 - 因此它不是局部變量問題。奇怪的是,崩潰總是在調試模式下發生,但只有在實際運行程序時的某些特定情況下才會發生。此外,儘管調試崩潰在所有計算機上都是可重現的,但運行時崩潰只發生在某些計算機上。非託管C++代碼將字符串發送到託管代碼的問題
我要指出,我有一個從非託管代碼出口許多功能,其中沒有引起除了這個功能的問題,另一個是做幾乎同樣的事情(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#中的字符串來解決問題。
'fileInfo'是'HashFile'中的一員?另一個線程是否可以修改'fileInfo'? – Henrik
命名風格:我會使用**「native」**而不是_「非託管」_(_「native C++」_,_「managed C#」_)。 –
@ Mr.C64謝謝你的筆記。 –