プログラマのつれづれなるままにプログラマのつれづれなるままに音宮志久が思ったことなどをネタにします。プログラムネタ・数学ネタがメインです。使用側から見たCOMとIUnknown使用側から見たCOMとIUnknownコメントを残すというわけで、ちょっと内部的に使っている技術の解説っぽいことをやってみましょう。日記の方はそれぞれの記事ごとでリンクがあるようなのでこれで書いても問題はないと思います。ゲームを作ろうとしたときに出てくるCOM(DirectXなどに使用されている技術)とIUnknownです。COMでは、プログラムとして使用するときにはすべてのオブジェクトがIUnknownに対応する、とあります。これは、つまりすべてのCOMのインターフェイスはIUnknownを継承しているような振る舞いをする、ということになります。正しくは、以下のような定義がある、ということですが・・・。Release(void);}後ろの2つ(AddRef,Release)は、このオブジェクトの解体のタイミングを操作している関数です。簡単に言うと、COMオブジェクトを複数のオブジェクトで共有して使用するときに共有先でAddRefを呼び出してオブジェクトの共有を開始します。必要がなくなるとReleaseを呼び出して対象のオブジェクトで不必要になったことを通知します。内部的な参照カウント(いくつのオブジェクトに所有されているか)を制御しているわけですね。使用者がもっとも困るのがQueryInterfaceです。この関数は一応以下のような解説がされています。オブジェクトに含まれる関数を利用したい場合は、そのオブジェクトのQueryInterfaceを呼び出し、目的の関数を実装したインターフェイスのポインタをリクエストします。ポインタおよび成功コードを返します。オブジェクトが目的のインターフェイスに対応していない場合は、エラー値が返されます。MSDN)対象のCOMオブジェクトがなんのインターフェイスを所持しているか、なんてヘルプを見てもわかりません。サンプルコードやチュートリアルにある程度です。ほとんどはサンプルコードの通り書くだけです。このQueryInterfaceにはその定義上おもしろい仕掛けがあります。以下のようなコードです。false;このとき、戻り値hrは必ずS_OKになります。ほとんどの場合、if文でfalseは戻りません。この作業は事実上以下のコードを実行したのと同じになります。S_OK;もちろん、COMオブジェクトはstatic_cast的な書き方をサポートしていません。QueryInterfaceでの要求を行うとアップキャストを行ったような状態になります。ダウンキャスト方向も全く同じ記述方法で安全に元に戻せます。実際にプログラムを書いて実行してみるとわかります。役に立たないようですが、すべてのオブジェクトはIUnknownを継承している「ような振る舞い」なのでこの記述は有効です。IUnknownを実際に継承していなくても3関数が実装されていて、QueryInterfaceでIUnknownが取得できるならそれはCOMのインターフェイスとして有効です。(これはDirectShowのフィルタを実装するときのベースクラスとなるCUnknownがこの考え方に基づいています。)QueryInterfaceを「機能の取得」以外にも「安全なダウンキャスト/アップキャスト(dynamic_cast)の代わり」としても使うことが出来るんですね~。IUnknown(インターフェイスなんてわかんないよ~<訳違)といっても馬鹿には出来ません。COMのベースインターフェイスとなる仕様ですね~。更新ペースが速いですが、更新です。コメントをキャンセルメールアドレスが公開されることはありません。気になるプログラムネタや数学ネタがあったら書き込みたいのだが残業が長すぎて眠気が全くとれず体調があまりよくない。過労などでぶっ倒れるかもしれない。あと、さすがに独り身が寂しいのでなんとかしたいと考えてはいるのだが...。アクセスカウンタアクセス数:スポンサーリンクモバイルバージョンに。