IPersistStream
COM公式ドキュメント
ストレージにシンプルなシリアルストリームを使用するオブジェクトの保存と読み込みを可能にします。
解説(Remarks)
このインターフェイスの用途の一つは、OLE モニカーの実装をサポートすることです。OLE が提供する各モニカーインターフェイスは、モニカーが自身を保存または読み込むための IPersistStream 実装を提供します。OLE の汎用複合モニカークラスのインスタンスは、コンポーネントである各モニカーの IPersistStream メソッドを呼び出し、単一のストリーム内に適切な順序でコンポーネントを読み込みまたは保存します。
IPersistStream の URL モニカー実装
IPersistStream の URL モニカー実装は URL モニカーオブジェクト上に存在し、このオブジェクトは IUnknown、IAsyncMoniker、および IMoniker をサポートします。IMoniker インターフェイスは IPersistStream からその定義を継承しており、そのため URL モニカーは IMoniker の実装の一部として IPersistStream の実装も提供します。URL モニカー上の IAsyncMoniker インターフェイスは単なる IUnknown です(追加のメソッドはありません)。これはクライアントがモニカーが非同期バインドをサポートするかどうかを判定できるようにするために使用されます。このオブジェクト上の IMoniker インターフェイスへのポインターを取得するには、CreateURLMonikerEx 関数を呼び出します。次に IPersistStream へのポインターを取得するには、QueryInterface メソッドを呼び出します。
IPersistStream は IUnknown からその定義を継承するのに加えて、IPersist の唯一のメソッドである GetClassID も継承します。
メソッド 4
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
オブジェクトが最後にストリームへ保存されて以降に変更されたかどうかを判定します。(IPersistStream.IsDirty)
戻り値
解説(Remarks)
このメソッドは、オブジェクトを閉じる前に保存すべきかどうかを判定するために使用します。オブジェクトのダーティフラグは、IPersistStream::Save メソッド内で条件付きでクリアされます。
呼び出し側への注意
エラーを示す戻り値はすべて、オブジェクトが変更されたことを示すものとして扱うべきです。このメソッドが明示的に S_FALSE を返さない限り、オブジェクトは保存する必要があると想定してください。なお、OLE が提供するモニカーインターフェイスにおける IPersistStream::IsDirty メソッドの OLE 提供実装は、内部状態が決して変化しないため、常に S_FALSE を返します。
以前に保存されたストリームからオブジェクトを初期化します。(IPersistStream.Load)
| pStm | IStream* | in | オブジェクトの読み込み元となるストリームを指す IStream ポインター。 |
戻り値
このメソッドは次の値を返すことがあります。
| 戻り値 | 説明 |
|---|---|
| メソッドは正常に完了しました。 | |
| メモリ不足のためオブジェクトは読み込まれませんでした。 | |
| メモリ不足以外の何らかの理由により、オブジェクトは読み込まれませんでした。 |
解説(Remarks)
このメソッドは、関連付けられたストリームからオブジェクトを読み込みます。シークポインターは、直近の IPersistStream::Save メソッド実行時と同じ状態に設定されます。このメソッドはストリームからのシークと読み取りは可能ですが、書き込みはできません。
呼び出し側への注意
通常は IPersistStream::Load を直接呼び出すのではなく、OleLoadFromStream 関数を呼び出します。この関数は次の処理を行います。- ReadClassStm 関数を呼び出して、ストリームからクラス識別子を取得します。
- CoCreateInstance 関数を呼び出して、オブジェクトのインスタンスを作成します。
- インスタンスに対して IPersistStream を照会します。
- IPersistStream::Load を呼び出します。
オブジェクトがこのパターンで格納されていない場合は、これらのメソッドを自分で個別に呼び出す必要があります。
URL モニカーに関する注意
通常は事前に IPersistStream::Save(OleSaveToStream を使用)によってストリーム内に格納されたデータから、URL モニカーを初期化します。URL モニカーのバイナリ形式は Unicode の URL 文字列です(完全な URL 文字列の場合と部分的な URL 文字列の場合があります。詳細は CreateURLMonikerEx を参照してください)。これは文字数を表す ULONG の後にその文字数分の Unicode 文字が続く形で表現されます。指定したストリームにオブジェクトを保存します。(IPersistStream.Save)
| pStm | IStream* | in | オブジェクトの保存先となるストリームを指す IStream ポインター。 |
| fClearDirty | BOOL | in | 保存完了後にダーティフラグをクリアするかどうかを示します。TRUE の場合、フラグをクリアします。FALSE の場合、フラグは変更しないままにします。 |
戻り値
このメソッドは次の値を返すことがあります。
| 戻り値 | 説明 |
|---|---|
| メソッドは正常に完了しました。 | |
| オブジェクトは自身をストリームに保存できませんでした。このエラーは、たとえばオブジェクトがストリームへシリアル化できない別のオブジェクトを含んでいる場合や、ISequentialStream::Write の呼び出しが STG_E_CANTSAVE を返した場合などを示している可能性があります。 | |
| ストレージデバイスに空き容量が残っていないため、オブジェクトを保存できませんでした。 |
解説(Remarks)
IPersistStream::Save は、指定したストリームにオブジェクトを保存し、オブジェクトがダーティフラグをリセットすべきかどうかを示します。
シークポインターは、オブジェクトがデータの書き込みを開始すべきストリーム内の位置に配置されます。オブジェクトは ISequentialStream::Write メソッドを呼び出してデータを書き込みます。
終了時には、シークポインターはオブジェクトデータの直後に配置されている必要があります。エラーが返された場合、シークポインターの位置は未定義です。
呼び出し側への注意
通常は IPersistStream::Save を直接呼び出すのではなく、OleSaveToStream ヘルパー関数を呼び出します。この関数は次の処理を行います。- GetClassID を呼び出して、オブジェクトの CLSID を取得します。
- WriteClassStm 関数を呼び出して、オブジェクトの CLSID をストリームに書き込みます。
- IPersistStream::Save を呼び出します。
OLE が提供する IPersistStream の実装も、この同じパターンに従います。
実装者への注意
IPersistStream::Save メソッドは CLSID をストリームに書き込みません。CLSID の書き込みは呼び出し側の責任です。IPersistStream::Save メソッドはストリームからの読み取り、ストリームへの書き込み、およびストリーム内のシークを行えますが、入力時のシークポインターより前の位置へシークしてはなりません。
URL モニカーに関する注意
URL モニカーをストリームに保存します。URL モニカーのバイナリ形式は Unicode の URL 文字列です(完全な URL 文字列の場合と部分的な URL 文字列の場合があります。詳細は CreateURLMonikerEx を参照してください)。これは文字数を表す ULONG の後にその文字数分の Unicode 文字が続く形で表現されます。オブジェクトの保存に必要なストリームのサイズを取得します。(IPersistStream.GetSizeMax)
| pcbSize | ULONGLONG* | out | このオブジェクトの保存に必要なストリームのサイズ(バイト単位)。 |
戻り値
このメソッドは、サイズが正常に取得されたことを示すために S_OK を返します。
解説(Remarks)
このメソッドは、オブジェクトの保存に必要なサイズを返します。IPersistStream::Save メソッドを呼び出す前に、このメソッドを呼び出してサイズを判定し、必要なバッファを設定できます。
実装者への注意
呼び出し側が拡張できないストリームを指定して IPersistStream::Save メソッドを呼び出す可能性があるため、GetSizeMax の実装は必要なサイズを控えめに(余裕を持って)見積もった値を返すべきです。URL モニカーに関する注意
このメソッドは、後続の IPersistStream::Save の呼び出しで必要となるストリーム内の最大バイト数を取得します。この値は sizeof(ULONG)==4 に sizeof(WCHAR)*n を加えたものであり、ここで n は NULL 終端文字を含む完全または部分的な URL 文字列の長さです。Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IPersistStream "{00000109-0000-0000-C000-000000000046}" #usecom global IPersistStream IID_IPersistStream "{}" #comfunc global IPersistStream_IsDirty 4 #comfunc global IPersistStream_Load 5 sptr #comfunc global IPersistStream_Save 6 sptr,int #comfunc global IPersistStream_GetSizeMax 7 var ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IPersistStream "{00000109-0000-0000-C000-000000000046}" #usecom global IPersistStream IID_IPersistStream "{}" #comfunc global IPersistStream_IsDirty 4 #comfunc global IPersistStream_Load 5 sptr #comfunc global IPersistStream_Save 6 sptr,int #comfunc global IPersistStream_GetSizeMax 7 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。