2

.NET アセンブリ/クラスをCOM 可視化できることが知られているため、アセンブリ内のクラスは、COM 対応クライアントによって COM オブジェクトとしてインスタンス化できます。

注意すべき「落とし穴」はありますか?

4

2 に答える 2

3

はい、はい、あります。

1) この種の相互運用性が必要となる特定のケースは、クラスが既存の COM インターフェイスを実装することが予想される場合です。たとえば、SharePoint は、カスタム インターフェイスを実装する COM クラスとしてプラグインが登録されるプラグイン アーキテクチャを提供します。

インターフェイスのPrimary Interop Assemblyがない場合は、TLB または TLB を含む DLL への参照を追加する必要があると思われます。参照を追加するときに [参照] を選択すると、Visual Studio で参照を追加できます。TLB がない場合は、を使用して TLB にコンパイルできる IDL が必要ですmidl.exe。一部のドキュメントtlbimp.exeでは、TLB で実行し、生成されたアセンブリへの参照を追加することを同様に提案しています。

でも...

  • おそらく、上記の方法を使用すると、クライアントはクラスの COM オブジェクト インスタンスを正常に作成できますが、そのクラスのメソッドを呼び出すとクラッシュします。これは、上記のメソッドがインターフェイス内のメソッドの順序を台無しにするためです。したがって、クライアントはいくつかのパラメーターを期待するメソッド A を呼び出そうとしますが、仮想テーブルのエントリ (クライアントが C++ であると仮定) は実際にはメソッド B を呼び出します!...そして、無効なパラメーターをマネージ実装にマーシャリングしようとします。
  • 変換されたパラメーターの型が正しくない場合があります (たとえば、 abyte*が に変換される場合がありますref byte)。
  • 一部のインターフェイスは正しく変換されていません (具体的には、変換された ILockBytes には と の代わりに と のメソッドが含まれていますRemoteReadAt) 。RemoteWriteAtReadAtWriteAt

そのため、TLB から自動生成されたアセンブリを出発点として使用できますが、アセンブリを変更するか、生成されたコードをソース ファイルにコピーしてから、必要な変更を加えて、上記のすべてを修正する必要があります。

2)ドキュメントで推奨されているように、タイプとしてClassInterfaceAttributewithを追加します。ClassInterfaceType.None

3) アーキテクチャのアセンブリをビルドし、Any CPUそれを登録する任意のマシンで -

  • 32 ビット プロセスで COM を使用するためにアセンブリを登録する場合は、 を使用して登録しC:\Windows\Microsoft .NET\Framework\<version>\regasm.exeます。
  • 64 ビット プロセスで COM を使用するためにアセンブリを登録する場合は、 を使用して登録しC:\Windows\Microsoft .NET\Framework64\<version>\regasm.exeます。

4) 実行しただけでregasm.exeは .NET アセンブリが GAC に追加されないため、自分でアセンブリを GAC にインストールしない場合は、必ず/codebasefor パラメータを使用してください。regasm.exe

5) Visual Studio が管理者権限で実行されている場合でも、ビルド オプションの [COM 相互運用に登録する] チェックボックスをオンにすると、アセンブリの登録が失敗することがよくあります。チェックボックスをオフにして、代わりにregasm.exeビルド後のイベントとして追加することをお勧めします。

于 2012-07-03T19:32:33.707 に答える
1

私が遭遇したカップル:

  1. COM はジェネリックをサポートしていないため、COM 経由でアクセスされるすべてのコレクションは型指定されていない必要があります。
  2. COM はインターフェイスの継承をサポートしていますが、.Net 実装はサポートしていません。COM はインターフェイスのみに関係するため、クラスで継承を使用できますが、インターフェイスには派生クラス メンバーと基底クラス メンバーの両方が含まれている必要があります。
于 2012-07-03T19:44:58.320 に答える