C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 131 を表示中)
■77681 / )  Re[7]: [COM]ITypeInfo からのインターフェイス取得方法
□投稿者/ とっちゃん (307回)-(2015/11/16(Mon) 11:39:49)
No77655 (kurage さん) に返信
> ■No77630 ((こ) さん) に返信
>
> (こ)さん、こんにちは。丁寧なソース付きでご回答下さいまして、誠に有難うございます。
> 返信が遅くなり、申し訳ございませんでした。
>
> 現時点で、コクラスの ITypeInfo については、取得できています。
>
> ご提示くださったソースの方法を試してみましたところ、幾つかのインターフェイスについては列挙されました。
> しかし、今回目的としている IConnectionPointContainer インターフェイスについては、取得することができませんでした。
>
> ※念のため、取得されたそれぞれのインターフェイスの ITypeInfo に対しても、同様に GetRefTypeInfo() を実行してみて確認しましたが、ダメでした。
>  (IDispatch が取得されるだけでした。)
>
一応...
No77630 で、(こ) さんが提示したソースは、あくまでも ITypeInfo オブジェクトに対する問合せです。

ITypeInfo は、タイプライブラリに対するアクセスをサポートするオブジェクトであって、実際に使いたいインターフェースの実体とは異なります。

多種多様な問い合わせができますが、返答の範囲はあくまでも該当するタイプライブラリに記載されたものの範囲でしかありません。

このあたりは、(こ)さんのサンプルを「ネイティブコードのデバッグを有効にする」のチェックを入れてデバッグ実行し
プロセス内にロードされたDLLを見てみるとわかります。

実装を持つ ShDocVw.dll がロードされることなく終了しているのが見れると思います。



> IConnectionPointContainer インターフェイスは、「OLE/COM Object Viewer (oleview.exe)」でも表示されないようです。
> ただ、COM オブジェクトのインスタンスを IConnectionPointContainer 型にキャストする事はできるため、確実に実装されてはいるようなのです。
> 何か、特別な検索方法を用いないとダメとか、あるのでしょうか…。

IConnectionPointContainer がOLE/COM Object Viewer に出てこないのは、単にタイプライブラリに記述がなされていないからです。

上述したように ITypeInfo は「タイプライブラリ」にアクセスして情報を得るためのものなので、それ以上でもそれ以下でもありません。
そのため、取得しうる情報はあくまでも「タイプライブラリ」の中にある情報となります。
そこに記述されていない範疇のものについては、それがどのようなものか?も含めて詳細を知ることはできません。

さて、イベントですが、タイプライブラリの中では coclass(CoCreateInsatnceに渡すCLSIDの型定義)にある程度推測できる情報があります。

サンプルとしては coclass WebBrowser のタイプライブラリ情報を抜粋してみました。
[
 uuid(8856F961-340A-11D0-A96B-00C04FD705A2),
 helpstring("WebBrowser Control"),
 control
]
coclass WebBrowser {
 [default] interface IWebBrowser2;
 interface IWebBrowser;
 [default, source] dispinterface DWebBrowserEvents2;
 [source] dispinterface DWebBrowserEvents;
};

coclass WebBrowser は、[default] のインターフェースとして IWebBrowser2 を定義しており、そのほかに IWebBrowser を定義していることがここから読み取れます。
また、[default]の[source]すなわち、イベントインターフェースとして、dispinterface DWebBrowserEvents2(DualInterface)を規定しており、合わせて
dispinterface DWebBrowserEvents もイベントインターフェースとして規定している
ということがわかります。

COMの「汎用イベント」は、IConnectionPointContainer を使ってイベントインターフェースを登録する仕組みを提供する規約があります。
そのため、イベントインターフェースを規定している coclass は、そのオブジェクトがイベントを通知可能であるすなわち
IConnectionPointContainer を通じて、あらかじめ規定したインターフェースを接続できることを意味しています。

と、coclass から読み取れるのはここまで。

ここからは、類推が働くことになります。
COMのオブジェクトは、CoCreateInstance 以外の手段でも構築が可能です。
ブラウザのDOMインターフェースと同じように。。。

そのため、間接的にクリエイトされ、coclass を持たないオブジェクトの場合、タイプライブラリにインターフェースだけあれば
それ以上は記述しなくてもいいというオプション的な扱いがあります。

では、そういったインターフェースはどのように規定を行うのか?ですが、こちらは「プログラマに対するリファレンス情報」を
通じて、規定が知らされます。

例えば、マネージメントオブジェクトがあり、そこから個別のインターフェースが取得できるような場合、
マネージメントオブジェクトは、coclass としてタイプライブラリに登録されていますが
個別のインターフェースは、インターフェースが定義されているだけで、coclass が定義されていないことが大半です。

要するにどういうことか?というと、「マニュアル読め!」ということになります。

不親切に聞こえるかもしれませんが、タイプライブラリ自身も一種のマニュアル(リファレンス)です。
そこに記載がないなら、さらに詳しいことはほかの情報を頼るしかないということになります。
具体的には、利用者向けのリファレンスマニュアル、あるいは作者本人、場合によってはソースコードそのものというところ。

このあたりが、COMが一般的になり切れなかった理由の一つであり、タイプライブラリが中途半端と呼ばれる所以でもあったりします。

これらにアクセスせず、なおかつ実際のオブジェクトもない状態で、そのオブジェクトにイベントを接続できるかを
調査する方法があるか?という問いに対しては「そんなものはこの地球上のどこにも存在しない」という冷たい答えを返しておくことにします。

返信 編集キー/


管理者用

- Child Tree -