2011-04-26 6 views
2

私はVBAから参照する必要があるライブラリを構築していますので、早期バインディングをサポートするためにタイプライブラリを用意する必要があります。私が見た例のほとんどは、COMに公開されているクラスのインタフェースを定義しています。COMに公開されている.NETクラスのインターフェイスを定義する利点は何ですか?

[Guid("D6F88E95-8A27-4ae6-B6DE-0542A0FC7039")]  
[InterfaceType(ComInterfaceType.InterfaceIsDual)]  
public interface IMyClass 

[Guid("13FE32AD-4BF8-495f-AB4D-6C61BD463EA4")]  
[ClassInterface(ClassInterfaceType.None)]  
[ProgId("MyNamespace.MyClass")]  
public class MyClass : IMyClass 

クラスがClassInterface.AutoDualを使用して直接インターフェイスを実装することに不利な点はありますか?より複雑なクラスの場合、どこのComVisible属性も使わずに、どのメンバーが公開されているかを明確に定義するためのインターフェースが好きです。しかし、私はCOM全体にさらされるイベントargsのようなかなり簡単なデータクラスもいくつか持っています。私は明示的にインターフェイス上のdispidsを設定する例を見てきました - これを行う利点はありますか?

+1

インターフェイスとClassInterfaceType.Noneが必要な理由については、この質問http://stackoverflow.com/q/1435295/57428を参照してください。 – sharptooth

答えて

5

はい、大きなものがあります:DLL地獄厄介な早期バインディングと。 COMクライアントは、vテーブルポインタを介してメソッドを直接呼び出します。同じインターフェイスIID(それ自体が犯罪である)を使用する古いCOMサーバーが常駐している場合、これは間違った方法または存在しない方法を呼び出すことがあります。ランタイム障害(通常はアクセス違反)は、診断が非常に困難です。

これは遅延バインディングでは発生しません。通常、DISP_E_MEMBERNOTFOUNDやDISP_E_BADPARAMCOUNTなどの合理的な診断が行われます。 MicrosoftがComInterfaceType.InterfaceIsIDispatchを大いに支持しているのはこのためです。短所は非常に遅いという欠点があります。もう1つは、コンパイル時ではなく、実行時にエラーが検出されるということです。

DispIDを設定することは非常にまれです。レガシーマイクロソフト製品の中には、dispidをコードにあらかじめコンパイルして使用するものもあります。 IDispatch :: GetIDsOfNames()呼び出しの必要がないため、遅延結合の約2倍の速さです。あなたがまだVBAのバージョンではなく、野生でそれらに遭遇することはほとんどありません。

トピックis hereについてのまともなKB記事

+0

私は記事を読んだ - ポインタのおかげで。あなたはバイナリ互換性について話していると思います。したがって、タイプライブラリを更新せずに新しいバージョンをインストールした場合、インターフェイスを使用してCOMインターフェイスを実装するコードのvtableレイアウトは同じままで、関数呼び出しはまだ動作しますか? – Shane

+0

IIDを再利用するというあなたの発言で少し混乱します。上記の例でインターフェイスに適用されたGUIDは、IIDによってどういう意味ですか?あなたは、「それ自体が犯罪ですか?」と言ったときに、コードの新しいバージョンがリリースされたときに、インタフェースのGUIDを変更する必要があると言っていますか?バージョン間の互換性も損なわないでしょうか? – Shane

+0

私はあなたがIIDを再利用しないということを知っていると思います。インターフェースは不変でなければなりません。つまり、IIDがインターフェースに割り当てられたら、それはコンポーネントの将来のバージョンで決して変更してはいけません。これは正しいです? – Shane

関連する問題