3

アンマネージ 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#

EDIT:コールスタックを更新しました[Managed to Native Transition]。問題があることを明確に示しているように見える行が表示されます。

どんな助けでも大歓迎です。前もって感謝します。

編集: C# CppToCsharpAdapter.GetFileInfo() 関数が IntPtr を返すようにし、それを C# 内の文字列に変換することで問題を解決しました。

4

2 に答える 2

0

DLL にエクスポートされた関数はrawGetFileInfo()を返しますが、これがマネージ コードの正しい型かどうかはわかりません (適切な P/Invoke 署名を使用しない限り...)。 const char*

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&のみ返すことをお勧めします(つまり、 ではなく単に return )。string string string&

于 2013-06-18T10:10:47.180 に答える