1

私たちのプログラムは、同じく私たちが作成した COM サーバーを使用する必要があります。シナリオは次のとおりです。インストーラーは、プログラム ファイルと COM サーバー ファイルの両方を、インストールごとに同じフォルダーにコピーします。

現在、regsvr32 を使用して COM サーバーを登録していますが、これはあまり良くありません。同じ COM サーバー (別のバージョンの可能性が高い) を使用する別の無関係なプログラムを開発すると、問題が発生する可能性があります。CLSID が変更されていないため、サーバーは後で登録されたプログラムは両方のプログラムで使用され、最初のプログラムが誤動作する可能性があります。

したがって、reg-free COM が必要です。マニフェストを使用することもできますが、しばらく使ってみたところ、ナイトリー ビルドで使用するにはあまり便利ではありませんでした。プログラムを書き換えて、 を呼び出す代わりに を呼び出しCoCreateInstance()てから、クラス ファクトリを見つけて取得し、それLoadLibraryEx()を使用するようにすることもできます。GetProcAddress()DllGetClassObject()

いくつかの欠点がすぐにわかります。

  • プログラムは、正確な COM サーバー ファイル名に依存します。
  • 通常は Windows で管理されるものについては、追加のコードを記述する必要があります。
  • COM サーバーはインプロセスである必要があり、マーシャリングは使用されません。

これらの欠点は、一般的にショー ストッパーになる可能性がありますが、特定のシナリオではまったく悪くはありません。

と比較してLoadLibraryEx()/を使用することで他に欠点はありますか?DllGetClassObject()CoCreateInstance()

4

2 に答える 2

1

私はあなたが説明した正確な手順に従って、独自の軽量バージョンの COM を実装します。COMの「アクティベーション」部分を置き換えることについて話している。COMアクティベーションモデルが提供するすべての機能をリストしていると思います:

  1. アウト プロセス/アパートメント スレッドのサポート
  2. CoClass ライブラリの場所を解決するためのレジストリを介したインダイレクション。新しいバージョン、代替実装などを可能にします。

ライブラリを動的にロードし、クラス ファクトリを取得し、オブジェクトを構築すると、COM 経由でアパートメント内にインプロセス オブジェクトを作成した場合と同じように動作するはずです。

于 2011-06-04T23:28:48.810 に答える
0

1 . プログラムは、正確な COM サーバー ファイル名に依存します。

DLL の遅延ロード通知フックと処理(つまり、ロードのプリエンプション) を使用dliNotePreLoadLibraryすることで、クライアントのインポート テーブルに記録されているものとは異なるファイル名を持つ DLL からロードできます。

実際、コマンド ラインで使用する実際の DLL ファイル名、または構成ファイルを指定することもできます。(最近やったばかりです。)時間になる前にライブラリを使用しようとしない限り。

2 . 通常は Windows で管理されるものについては、追加のコードを記述する必要があります。

に関してはGetProcAddressdelay-load ヘルパー ユーティリティは、単一のモジュールからすべてのインポートを一度にロードする機能を提供します。

3 . COM サーバーはインプロセスである必要があり、マーシャリングは使用されません。

マーシャリングに関しては、私はこの分野に精通していませんが、いくつかのアイデアがあります:

  • 独自のプロキシ/スタブ コードを実装する必要があります。プロセス間通信を独自の方法で処理します。

これは、独自のマーシャリング コンパイラを作成する必要があることを意味します。他の人がすでにそれを行っていることに気付くかもしれません。

それが完了すると、クライアントはLoadLibraryプロキシになり、プロキシはスタブ実行可能ファイル (プロセス外) を起動してサーバーをホストし、スタブはLoadLibrary実際のサーバーになります。

これは基本的に、COM を完全に再発明したものです。

于 2011-06-05T00:18:27.320 に答える