ファイルを開いて保存するダイアログの共通ダイアログHWNDからIShellBrowserインターフェイスポインタを取得する、文書化されていないメッセージが存在することを指摘する人もいます。
しかし、そのポインターがAddRefされているのか、それとも返される生のアドレスだけであるのか、Release()を呼び出さないのかについて、矛盾する情報(または情報がない)がありますか?
ファイルを開いて保存するダイアログの共通ダイアログHWNDからIShellBrowserインターフェイスポインタを取得する、文書化されていないメッセージが存在することを指摘する人もいます。
しかし、そのポインターがAddRefされているのか、それとも返される生のアドレスだけであるのか、Release()を呼び出さないのかについて、矛盾する情報(または情報がない)がありますか?
いいえ。次のリンクが役立つ場合があります。コンポーネントオブジェクトモデルのルール。
抜粋:
参照カウントルール
ルール1:インターフェイスポインタの新しいコピーごとにAddRefを呼び出す必要があり、後続のルールで明示的に許可されている場合を除き、インターフェイスポインタを破棄するたびにReleaseを呼び出す必要があります。
次のルールは、ルール1の一般的な非例外を示しています。
- ルール1a:関数への入出力パラメーター。呼び出し元は実際のパラメーターをAddRefする必要があります。これは、出力値がその上に格納されたときに呼び出し先によって解放されるためです。
- ルール1b:グローバル変数のフェッチ。グローバル変数内のポインターの既存のコピーからフェッチされたインターフェイスポインターのローカルコピーは、ローカルコピーがまだ存続している間に呼び出された関数がグローバル内のコピーを破棄する可能性があるため、独立して参照カウントする必要があります。
- ルール1c:「薄い空気」から合成された新しいポインタ。他のソースから取得するのではなく、特別な内部知識を使用してインターフェイスポインターを合成する関数は、新しく合成されたポインターに対して最初のAddRefを実行する必要があります。このようなルーチンの重要な例には、インスタンス作成ルーチン、IUnknown::QueryInterfaceの実装などがあります。
- ルール1d:内部に格納されたポインタのコピーを返す。ポインタが返された後、呼び出し先は、その存続期間が、内部に格納されているポインタのコピーの存続期間とどのように関連しているかを知りません。したがって、呼び出し先は、ポインタコピーを返す前に、ポインタコピーに対してAddRefを呼び出す必要があります。
ルール2:インターフェイスポインタの2つ以上のコピーの有効期間の開始と終了の関係に関するコードの一部に関する特別な知識により、AddRef/Releaseペアを省略できます。
- COMクライアントの観点からは、参照カウントは常にインターフェイスごとの概念です。クライアントは、オブジェクトがすべてのインターフェイスで同じ参照カウントを使用していると想定してはなりません。
- AddRefとReleaseの戻り値は信頼できず、デバッグ目的でのみ使用する必要があります。
- ポインターの安定性; 詳細については、OLEヘルプファイルの「参照カウントルール」のサブセクション「このポインタの安定化と有効性の維持」を参照してください。
参照カウントの詳細については、DouglasHodgesによる優れた「ManagingObjectLifetimes in OLE」技術記事、およびKraig Brockschmidt(MSDN Library、Books)によるInside OLE、第2版の第3章を参照してください。