2009-04-28 11 views
9

私のC++ DLLの関数で、std :: stringをC#アプリケーションに返します。これはかなりのようになります。C++ DLLからC#DLLへのstd :: stringを返す - > RtlFreeHeapに指定された無効なアドレス

std::string g_DllName = "MyDLL"; 

extern "C" THUNDER_API const char* __stdcall GetDLLName() 
{ 
    return g_DllName.c_str(); 
} 

しかし、私のC#のコードは、この関数を呼び出すときに、私は私の出力ウィンドウにこのメッセージが表示されます:

Invalid Address specified to RtlFreeHeap(00150000, 0012D8D8) 

C#での関数宣言は次のようになります。

[DllImport("MyDll", EntryPoint = "GetDLLName")] 
    [return: MarshalAs(UnmanagedType.LPStr)] 
    public static extern string GetDLLName(); 

私がオンラインで見つけたことから、新しいバージョン(デバッグやリリースなど)が削除に使用されている間に矛盾があると、このメッセージが表示されることがあります。しかし、それが私の場合に起こっているのかどうかはわかりません。だから私はそれが何を引き起こしているのかは分かりません。多分MashallAsはそれと関係があるかもしれない?

アイデア?

ありがとうございます!

+0

あなたはすなわち、A見つかったかどうか確認することができます)あなたは、デバッグのために正しい(デバッグ)ライブラリを使用している場合には、などのビルドおよびb)この問題は、両方のデバッグ中に発生し、 c)あなたのC++ dllに/ clrの代わりに/ clr:pureを使ってみてください。 – dirkgently

答えて

12

私は問題を見つけることができました。それはC#の定義が行われた方法でした。私が理解できることから、MarshallAs(UnmanagedType.LPStr)を文字列の戻り値の型と組み合わせて使用​​すると、完了したときに文字列を解放しようとします。しかし、文字列はC++ DLLから来ており、おそらく完全に異なるメモリマネージャであるため、失敗します。とにかくそれが失敗しなかったとしても、私はそれがとにかく解放されることを望んでいません。

私が見つけた解決策は、これにC#の宣言を変更することでした(C++のコードが変更されません):

[DllImport("MyDll", EntryPoint = "GetDLLName")] 
public static extern IntPtr GetDLLName(); 

それは単なる文字列データへのポインタを返すようにだから、これはそれを作ります。そしてMarshal.PtrToStringAnsi(に渡し、それを文字列に変更するために)

return Marshal.PtrToStringAnsi(GetDLLName()); 

そして、それは清潔のための別の関数に包まれます。

私は、このページから解決策を見つけた: http://discuss.fogcreek.com/dotnetquestions/default.asp?cmd=show&ixPost=1108

関連する問題