1

マネージ C++ ラッパーを介して C# コードを呼び出すアンマネージ C++ DLL があります。アンマネージド c++ DLL は、一部のアプリケーション (私の制御外) のプラグインです。このアプリケーションがアンマネージ C++ DLL を呼び出すと、マネージ C++ コードが C# コードを使用しようとするまで、すべて正常に動作します。その後、クラッシュします。

アプリケーションと同じことを行うテスト アプリケーションを作成しました。つまり、アンマネージ c++ DLL を呼び出します。これはうまくいきます。

コードは可能な限り単純です。

アンマネージ C++:

extern "C" __declspec(dllexport) void UnmanagedMethodCalledUponByApplication()
{
    new Bridge();
}

マネージ C++:

Bridge::Brigde()
{
    gcnew Managed(); // This line crashes
}

c#:

public class Managed
{
}

問題のある行の周りに try-catch (...) ブロックを追加しようとしましたが、エラーをキャッチしません。

gcnew Managed();行を置き換えると、正常にMessageBox::Show("Alive!");動作します。私の推測では、C# プロジェクトの設定に問題があると思われます。

さまざまなプラットフォーム (任意の CPU および x86) でコンパイルしようとしました。ターゲット フレームワークを変更しようとしました。Managedを使用する代わりに、静的メソッドを呼び出そうとしましたgcnew。まだクラッシュしています。

何が問題なのですか?

アップデート:

コメントと回答でアドバイスした後、デバッガーを添付しました。System.IO.FileNotFoundExceptionマネージ DLL (またはその依存関係の 1 つ) が見つからないというメッセージが表示されるようになりました。

推測は次のとおりです。DLL は一緒に配置されますが、現在のディレクトリには配置されていません。アンマネージ c++ DLL は、メイン アプリケーションがそのパスを指定するため、正しくロードされます。マネージ C++ は実際には lib であるため、コードも正常に機能します。しかし、マネージ C++ が c# DLL をロードしようとすると、間違ったディレクトリで検索されます。

アップデート:

これを修正する方法は、リフレクションを使用して c# DLL を動的にロードすることです。

4

1 に答える 1

1
  extern "C" __declspec(dllexport) 

はい、これは、マネージ コードを実行できるように CLR を読み込んで初期化する必要なスタブをコンパイラに生成させる安価で簡単な方法です。問題は、マネージ コードによってスローされた例外を処理するための適切な処理が何も行われないことです。また、マネージ コードは例外をスローするのが好きで、優れたトラブルシューティング ツールです。例外情報を取得する方法がない場合、それは素晴らしいことではなくなります。

ネイティブ コードから実行できる最善の方法は、__try/__exceptキーワードを使用してマネージ例外をキャッチすることです。例外コードは 0xe0434f4d です。しかしそれでも、必要な情報、例外メッセージ、聖なるスタック トレースにアクセスすることはできません。

デバッグできます。プロジェクト + プロパティ、デバッグ、デバッガーの種類を「混合」に変更します。次に、Debug + Exceptions で、CLR Exceptions の Thrown チェックボックスをオンにします。例外がスローされるとデバッガーが停止するため、何が問題なのかを確認できます。

コードを出荷した後に適切な診断を行うには、より優れた相互運用メカニズムが必要です。COM 相互運用機能を使用したり、CLR を自分でホストしたりします。

于 2012-11-16T17:43:56.023 に答える