3

これはかなり複雑なので、我慢してください。ネイティブ (Win32 のみ) C++ でコーディングされたサードパーティ プログラム (「ターゲット」) があります。ターゲットの設計の一部として、dll プラグイン システムを実装します。ネイティブ DLL は、プログラムの「ext」ディレクトリに配置されると、ターゲットによってロードされます。次に、ターゲットは、各 DLL が提供する 4 つのメソッド (Initialize、SendHook、RecvHook、Terminate) を適宜呼び出します。関数名から推測できるように、アドインは特定の関数をターゲットにフックします。ターゲットへのソース コードがありません。

アドインの 1 つは古くてバグがあります。それは Delphi で書かれています (もちろん、win32 DLL としてコンパイルされています)。ここ数週間、私はアドインを強化し、C# に変換してきました (これを「拡張機能」と呼びます)。完成したので、ターゲットに拡張機能 (クラス ライブラリとしてビルドされたもの) をロードさせることに注意を向けました。

明らかに、ターゲット (ネイティブ C++) は拡張機能 (マネージ C#) を直接ロードできません。したがって、調べてみると、拡張機能をロードし、ターゲットから拡張機能にメソッド呼び出しを渡す処理を行う「プロキシ」DLL (CLR サポート付きの VC++ で記述) が必要なだけのようです。

"単純。" そうだね。私は今、スキットルズの袋に入ったカメレオンよりも混乱しています. 拡張機能がいくつかのメソッドを呼び出すため (ハンドルによってプロキシに渡される)、パフォーマンスとプロセスメモリの権利の両方の観点から、COM の使用を避ける必要があることは明らかです。また、tlb ディレクティブと #import ディレクティブについても見てきました。これも正しい方法ではないようです。

この記事https://sites.google.com/site/srinivasnzd/csincppviacpp-cliに出くわしました。これは、ようやく正しい軌道に乗っているようです。実際、C++ プロキシからマネージ C# を問題なく呼び出すことができます。おまけとして、関数はプロキシを介して対応する管理対象を適切に呼び出すことができるようです(まだ実際のターゲットでテストすることはできませんでした) 。__declspec(dllexport)しかし今、質問が飛び出し始めました。

  • 純粋なネイティブ プロセスで CLR 対応の DLL を読み込むことはできますか? 基本的に CLR 対応コードから静的ライブラリを作成し、それを純粋なネイティブ コードとリンクして、「部分的に管理され、部分的にネイティブ」なプロキシ DLL を作成することについて誰かが話しているのを見たことがあります。しかし、その時点で混乱が始まり、そのトピックが私がやろうとしていることに適用できるかどうかさえ確信が持てませんでした.
  • DWORD アドレスを IntPtr にマーシャリングするにはどうすればよいですか (そして、C# 側で関数ポインターにマーシャリング解除します)。
  • AppDomains の言及を見ました。これは私が心配する必要があるものですか?
  • プロキシ DLL を実行するには、マネージ拡張 DLL を同じフォルダーに配置する必要があると想定しています。それをロードするために何か特別なことをする必要がありますか?それとも CLR とリンカーがそれを処理しますか?
  • 出力 DLL に加えて、".exp"、".ilk"、および ".lib" の拡張子を持つファイルを取得しています。これらは静的リンク用だと思いますが、DLL を使用するときは無視できますか?
4

1 に答える 1

2

C++ ラッパーを使用せずに C# コードをエクスポートするためのこのテンプレートをご覧ください。
残念ながら、そのままでは DllExport 属性がないため、C++ ラッパーが必要になるか、エクスポートを実行するために IL コードを変更する必要があります。
アドレスのマーシャリングは問題ではありません。C# 側の関数ポインターには注意してください。GC コレクターからそれらを遠ざけるための参照があることを常に確認する必要があるためです。静的参照を保持すると最も簡単です。GC はアンマネージ コード内の関数ポインターへの参照を認識できないため、クリーンアップされる可能性があります。
アプリ ドメインは、複数の C# モジュールがある場合に問題になります。これらが同じコードを共有している場合は、さらに問題になります。
exp はリンカーから取得されます。ilk と lib はリンカーに関連しているため、コピーする必要はないと思いますが、デバッグ時に必要になる場合があります。

于 2012-07-02T05:50:52.133 に答える