2011-08-22 16 views
5

私のアプリケーションはC#とC++のコードが混在しています。 C#で記述された起動モジュールは、COM(Component Object Model)メカニズムを介して初期化フェーズC++モジュールの間に読み込まれます。私はC#の部分にwcfサービスを追加することに決めたまで、すべてが正しく機能していました。すべてのwcfサービス呼び出しは、COMを使用してC++コードにルーティングされます。いくつかの新しいメソッドを追加した後、私は出力ウィンドウでメモリリークに気付きました。そこで、スクリーンショットからわかるように、C++クラスのデスクトラクタにブレークポイントを追加しました。この時点から奇妙なことが起こり始めました。プログラムがブレークポイントに達した後、予期せずクラッシュします。最初の奇妙なことは、ブレークポイントを設定せずにプログラムを実行すると、優雅に終了するということです。 2つ目の奇妙なことは、デバッガなしで実行しているかのようにプログラムがクラッシュするということです。 「Open in debugger」(またはこのようなもの)のボタンをクリックした後、「プログラムは既にデバッガの下で開かれています」というエラーメッセージが表示されます。エラーの原因を指摘する可能性のあるメッセージは出力ウィンドウに表示され、疑わしいコードはありません。 メッセージボックスをデストラクタに追加すると、メッセージボックスに表示されている内容を読む機会をユーザに追加することなく、アプリケーションのクローズが数秒で表示されます。必死に何か手掛かりを探す。COMオブジェクトデストラクタをデバッグするときに奇妙なクラッシュが発生する

P.S.問題は、wcfメソッドが少なくとも1回呼び出されたときにのみ発生します。この特定の呼び出しのプログラムフローがC++レベルにルーティングされたかどうかに依存しません。 C++からのC#を呼び出す場合、時にはガベージコレクタが正しくプログラム終了前に呼び出されません

enter image description here

enter image description here

+0

VSデバッガの代わりにWinDbgを使用して、クラッシュに関する詳細情報を取得してください – SpaceghostAli

答えて

0

。結論を下すために、私の主な間違いは、C#コードでCOMオブジェクトを明示的に解放することを忘れてしまったことです。ガベージコレクタがメモリを管理するタスクを遂行しても、他のプログラミング言語で書かれたモジュールではそうではありません。特定のダイナミックリンクライブラリをメモリからアンロードするときにCOMデストラクタが非常に最近呼び出され、これにより問題が発生しました。私はそれを十分にはっきりと説明したいと思います。

1

。 C#コードの最後にガベージコレクションを強制してください。このつの他の基準は、C++コードにぶら下がった横

public void Dispose() 
{ 
    Marshal.Release(internal_interface_ptr); 
    internal_interface_ptr = IntPtr.Zero; 
    Marshal.ReleaseComObject(internal_interface); 
    Marshal.ReleaseComObject(internal_interface); 
    internal_interface = null; 
} 

:コードに従うことによって解決さ

+0

クラッシュは、奇跡がなくなったようにもかかわらず、プログラムはすべてのCOMデストラクタが作業を終了する前に終了します。私の2番目のスクリーンショットを見てください。この正確な瞬間に、プログラムは終了直前ですが、まだ呼び出されていないCOMデストラクタもあります。彼らが呼び出された後、彼らの仕事は突然終了する。 – truthseeker

+0

次のコードで解決されました: public void Dispose() { Marshal.Release(internal_interface_ptr); internal_interface_ptr = IntPtr.Zero; Marshal.ReleaseComObject(internal_interface); internal_interface = null; } – truthseeker

+0

「奇跡が消えたかのようにクラッシュする」という言い回しが、私はかなり分かりません。私はガーベースコレクターを呼び出す前にあなたのサービスを処分するように強制する必要があるかもしれないと思う。 Garbaseコレクタが実行される前にServicesToRunまたはサービスが破棄されていることを確認してください。 – mydogisbox

関連する問題