質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
COM

COM(Component Object Model)はMicrosoftによるコンポーネントテクノロジーであり、 ソフトウェアの再利用を目的とした技術を指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

Q&A

解決済

1回答

12100閲覧

IUnknown::QueryInterface メソッドが良く理解できません。

watarusugimoto

総合スコア47

COM

COM(Component Object Model)はMicrosoftによるコンポーネントテクノロジーであり、 ソフトウェアの再利用を目的とした技術を指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

1グッド

0クリップ

投稿2016/11/13 06:19

###IUnknown::QueryInterface メソッド

Microsoftの「CまたはC++によるDirectXプログラミング>COM の使い方>IUnknown」
によると以下の様に書かれています。

オブジェクトが特定のコンポーネント オブジェクト モデル (COM) インターフェイスをサポートしているかどうかを判別する。インターフェイスがサポートされている場合、システムはオブジェクトの参照カウントを増やし、アプリケーションは、そのインターフェイスをすぐに使える。

C++

1HRESULT QueryInterface(REFIID riid,LPVOID *ppvObj);

パラメータ
riid: 要求するインターフェイスの参照識別子
ppvObj: 目的のインターフェイスがサポートされている場合に、インターフェイスへのポインタが格納されるポインタ変数のアドレス。

戻り値
成功した場合は、S_OK を返す。
失敗した場合は、E_NOINTERFACE または E_POINTER を返す。コンポーネントには、これらのエラー値に対する独自の定義をヘッダー ファイルに格納しているものもある。たとえば、Microsoft® DirectInput® では DIERR_NOINTERFACE は E_NOINTERFACE に等しい。

注意
このメソッドの呼び出しにより取得したインターフェイスを使う必要がない場合は、そのインターフェイスの IUnknown::Release メソッドを呼び出してインターフェイスを解放しなければならない。IUnknown::QueryInterface メソッドにより、Microsoft およびサード パーティ各社は、機能を妨害することなくオブジェクトを拡張できる。

###該当のソースコード

#include <stdio.h> #include <dshow.h> #define FILENAME L"mpeg2_mpeg2_ac3.mpg" int main() { IGraphBuilder *pGraphBuilder = NULL; IMediaControl *pMediaControl = NULL; // COMを初期化 CoInitialize(NULL); // FilterGraphManagerを生成 CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (LPVOID *)&pGraphBuilder); // MediaControlインターフェース取得 pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID *)&pMediaControl); // Graphを生成 pMediaControl->RenderFile(FILENAME); // 再生開始 pMediaControl->Run(); // 再生中にプログラムが終わってしまわないように MessageBox(NULL, "Block Execution", "Block", MB_OK); // 資源を解放 pMediaControl->Release(); pGraphBuilder->Release(); // COM終了 CoUninitialize(); return 0; }

###分からないこと

  • リストIUnknown::QueryInterface メソッドの説明で言うところのオブジェクトとは、該当のソースコードの中で言うと生成したFilterGraphManagerのことで良いのでしょうか?
  • 「特定のコンポーネント オブジェクト モデル (COM) インターフェイスをサポートしているかどうかを判別する」とありますが、該当のソースコードの中で言うと特定のとはどのようなインターフェイスのことを指しているのでしょうか?
  • 「インターフェイスがサポートされている場合、システムはオブジェクトの参照カウントを増やし、アプリケーションは、そのインターフェイスをすぐに使える。」とありますが、該当のソースコードの中で言うとアプリケーションとは何に該当するのでしょうか?

以上の通り、全く見当がついていなくて申し訳ありませんが、ここを読んだ方が良い等のご指摘いただけるとありがたいです。
初心者ですがよろしくお願いします。

unikumaを押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

生成したFilterGraphManagerのことで良いのでしょうか?

はい、それであっています。

特定のとはどのようなインターフェイスのことを指しているのでしょうか?

全てのCOMインターフェイスは自信を示す固有のインターフェイスID(IID)を持っていて
ここでいう「特定」はQueryInterfaceで指定したIIDをもつインターフェイスです。
つまりIMediaControlですね。

1つのオブジェクトは複数のインタフェースを実装する/または内部に持つことができて、
QueryInterfaceで知っているインターフェイスが指定されたらそのインターフェイスへのポインタを第2引数へ設定して成功を返します。。
知らないインターフェイスなら失敗を返すので「サポートしているかどうかを判別する」となっているんだと思います。

該当のソースコードの中で言うとアプリケーションとは何に該当するのでしょうか?

QueryInterfaceの呼び出し元、つまり今開発しているアプリそのものの事です。

COMはどのようなオブジェクトでも操作の流れは

  1. CoCreateInstanceでクラスのインスタンスを生成して、
  2. QueryInterfaceでインターフェースを問い合わせ
  3. インターフェイスのメソッドの呼び出しなど使用し
  4. インターフェイスが必要なくなったらReleaseを呼ぶ
    (インスタンスはReleaseが呼ばれてカウンタが0になったら自身を破棄します)

となります。
クラスの実装そのものは見えずインターフェースを通してクラスの一部分を操作するような感じです。

投稿2016/11/13 07:57

toki_td

総合スコア2850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

watarusugimoto

2016/11/13 08:48

良くわかりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問