Ruby 2.3.0 リファレンスマニュアル > ライブラリ一覧 > win32oleライブラリ > WIN32OLEクラス > ole_query_interface
ole_query_interface(iid) -> WIN32OLE
[permalink][rdoc]IID(インターフェイスID)を指定してオブジェクトの別のインターフェイスを 持つオブジェクトを取得します。
オブジェクトが複数のオートメーション用インターフェイスを持つ場合に、当 メソッドを利用して既定のインターフェイスとは異なるインターフェイスを取 得します。
ie = WIN32OLE.new('InternetExplorer.Application') ie_web_app = ie.ole_query_interface('{0002DF05-0000-0000-C000-000000000046}')
上例のie_web_appは、ieと同じインスタンスとなります。
COMの仕様では1つのインターフェイスについて同じIID問い合わせに対しては常 に同一のインターフェイスを返すことが決められています。
このため、正しく実装されたOLEオートメーションサーバでは本メソッドが意味 を持つことはありません。というのは、2つ以上の異なるWIN32OLEで操作可能な インターフェイスを持つということは、IID_IDispatch(OLEオートメーション のインターフェイスID)を指定した問い合わせに対して異なるインターフェイ スを返すということになるからです。これは、結果的に呼び出し側プログラム がいつでも間違えたインターフェイスを呼び出す可能性を持つということを意 味します。当然、それはサーバ実装のバグです。
問題は、C++のvtblアクセスや.NET FrameworkのCOM Interopのために静的型情 報が必要となることです。このため、一度あるインターフェイスを返すことに 決めた場合、実際に返すインターフェイスが元のインターフェイスを継承して いたとしても、ドキュメント上は異なるインターフェイスとして定義しなけれ ば追加のメソッドが呼び出せません。
たとえば、当メソッドの存在理由である http://www.ruby-forum.com/topic/109954(なお、元のパッチと異な りGUIDの統一フォーマットを利用するように改造されているため、IIDの前後に {}が必要です)には、Solutionオブジェクトに対してSolution2オブジェクトの 取得を依頼するために、必要ということになっています。実際、Solutionプロ パティが返すのは、この場合はSolutionインターフェイスを継承した Solution2インターフェイスです。しかし、Solutionプロパティの型情報は Solutionインターフェイスを返すことになっているため、静的に型を解決して いる場合は、追加のメソッドの呼び出しを記述できません。
しかし、WIN32OLEが利用するIDispatchインターフェイスは、メソッド名による 動的なメソッド検索が行われます。このため、Solutionオブジェクト(しかし その実態はSolution2オブジェクト)に対してSolution2で追加されたメソッド (たとえばGetProjectTemplate)を指定したとしても正しく呼び出せます。つ まり、http://www.ruby-forum.com/topic/109954で例示されているよ うなole_query_interfaceメソッドの呼び出しは不要です。
もし、当メソッドの呼び出しが本当に必要なのであれば、まず、該当するOLEオー トメーションサーバの修正を依頼してください。その実装は正しくありません。
正しく実装されたオブジェクトに対して当メソッドを適用すると、結果として、 同一オブジェクトの参照カウント値を無駄に増加させることになります。
なお、サポートしているインターフェイスのバージョンを調べたい場合に、以 下のような方法で、インターフェイスのバージョンを調べることができます。
def check_solution_version(obj) [['{CDA7305C-78B6-4D9D-90AD-93EBE71F9341}', 4], ['{DF23915F-FDA3-4DD5-9CAA-2E1372C2BB16}', 3], ['{FA238614-FBB1-4314-A7F7-49AE8BB6C6BA}', 2]].each do |iid, ver| begin intf = obj.ole_query_interface(iid) intf.ole_free return ver rescue WIN32OLERuntimeError end end 1 end
しかし、ole_query_interfaceのような特異なメソッドを利用するよりも、 WIN32OLE.new('VisualStudio.DTE.8.0') のように生成時にバージョン番号(こ の例では8.0)を指定するほうが良いスタイルです。
また、単に特定のメソッドをサポートしているかどうかを知りたいだけであれ ば、WIN32OLE#ole_respond_to?を利用したダックタイピングをしてくだ さい。