2

私は、マネージ コードによって消費されるメディア ファンデーション フレームワークを介して C++/CLI でいくつかの基本的なオーディオ プレーヤー機能を実装するこのライブラリを作成しています。オーディオの再生、停止、一時停止などは問題なくできます。Media Foundation に慣れていない人のために説明すると、メディア セッションは、通知用に処理できるイベントを投稿します。これは、セッション オブジェクトで IMFAsyncCallback オブジェクトを使用して BeginGetEvent を呼び出すことによって行われます。IMFAsyncCallback は、イベントを処理するために実装する必要があるメソッド Invoke(IMFAsyncResult) を定義します。イベントが発生すると、invoke メソッドは、イベント情報を照会できる IMFAsyncResult オブジェクトを使用して作業スレッド上のセッション オブジェクトによって呼び出されます。この結果オブジェクトは、イベント スレッドによって作成および所有されます。

私の Invoke の実装では、渡された IMFAsyncResult オブジェクトを使用して何か (QueryInterface の呼び出しなどを含む) を実行しようとすると、System.AccessViolationException が発生します。IMFAsyncCallback を実装したオブジェクトは、CRT ヒープに割り当てられた基本的な C++ クラス (管理されていない) であり、イベントは CRT ヒープに割り当てられたセッション オブジェクトが所有するスレッドに投稿されます。

  1. この例外の原因は何ですか?

  2. 従来の C++ で実装されたコードから .NET マネージ例外がスローされるのはなぜですか? 混合モードのアセンブリを使用すると、まさにそれが起こりますか?

4

2 に答える 2

10

クラッシュ ダンプをキャプチャし、分析のために VS 2010 または WinDbg にロードすると、すべてが明らかになります。VS 2010 の方が簡単ですが、WinDbg の方が効果的かもしれません。

WinDbg の使用はより複雑なオプションであるため、詳しく説明します (ターゲット プラットフォームに応じて、次の 32 ビット バージョンまたは 64 ビット バージョンを選択します)。

.sympath srv*<SymbolCacheDir>*http://msdl.microsoft.com/download/symbols

  • クラッシュ ダンプ ファイルを WinDbg に読み込みます ([ファイル] -> [クラッシュ ダンプを開く...])。
  • モジュールのデバッグ シンボルを構成する

.sympath+ <PrivatePdbDir>

  • SOS拡張機能を WinDbg に読み込む

.loadby sos mscorwks; * fw 2-3.5

また

.loadby sos clr; * fw 4

  • SOSEX拡張機能をダウンロードして抽出し、WinDbgに読み込みます

.load <Sosex32or64Dir>\sosex

  • WinDbg に分析を任せる

!analyze -v

  • SOSEX を使用して現在のスレッド スタックを表示します (マネージド フレームとアンマネージド フレームの両方を含む)

!mk

これはおそらくあなたの質問に答えます。

于 2010-09-07T02:36:32.790 に答える
1

これを簡単に再現できるようです。プログラムの実行中にデバッガーを接続し、アクセス違反が発生した時点でアクセス違反をトラップできるようにすることで、問題をデバッグできるはずです。多くの場合、ライブラリはこれをラップして別のタイプとして表示し、例外の元のサイトは明らかではありません。

Visual Studio からプロセスにアタッチするには、こちらを参照してください。不正なプロセスにアタッチするときは、ネイティブ コードとマネージ コードをデバッグするオプションを必ず選択してください。可能な限り、アセンブリと DLL のシンボルがシンボル パスで使用できることを確認してください (サードパーティ コードの場合、使用できないものもあります)。

アクセス違反をソースでデバッグできるように例外構成を変更するには、こちらを参照してください。

于 2010-09-25T12:11:20.543 に答える