次の方法で共有


CreateILockBytesOnHGlobal 関数 (coml2api.h)

CreateILockBytesOnHGlobal 関数は、HGLOBAL メモリ ハンドルを使用して、複合ファイルのメモリ内ストレージ用のバイトを格納するバイト配列オブジェクトを作成します。 このオブジェクトは、 ILockBytes インターフェイスの OLE で提供される実装です。

返されるバイト配列オブジェクトは、読み取りと書き込みの両方をサポートしますが、領域ロックはサポートしていません。 オブジェクトは GlobalReAlloc 関数を呼び出して、必要に応じてメモリ ブロックを拡張します。

構文

HRESULT CreateILockBytesOnHGlobal(
  [in]  HGLOBAL     hGlobal,
  [in]  BOOL        fDeleteOnRelease,
  [out] LPLOCKBYTES *pplkbyt
);

パラメーター

[in] hGlobal

GlobalAlloc 関数によって割り当てられたメモリ ハンドル。NULL の場合は、代わりに新しいハンドルが割り当てられます。 ハンドルは、移動可能および非カード可能として割り当てる必要があります。

[in] fDeleteOnRelease

オブジェクトが解放されたときに、このバイト配列オブジェクトの基になるハンドルを自動的に解放するかどうかを指定するフラグ。 FALSE に設定されている場合、呼び出し元は最終リリース後に hGlobal を解放する必要があります。 TRUE に設定すると、最終リリースでは hGlobal パラメーターが自動的に解放されます。

[out] pplkbyt

新しいバイト配列オブジェクトへのインターフェイス ポインターを受け取る ILockBytes ポインター変数のアドレス。

戻り値

この関数は、標準の戻り値 E_INVALIDARGE_OUTOFMEMORYをサポートします。また、次に示します。

注釈

hGlobalNULL の場合、CreateILockBytesOnHGlobal は新しいメモリ ハンドルを割り当て、バイト配列は最初は空になります。

hGlobalNULL でない場合、バイト配列オブジェクトの初期コンテンツはメモリ ブロックの現在の内容になります。 したがって、この関数を使用すると、メモリ内の既存のバイト配列を開くことができます。たとえば、 StgCreateDocfileOnILockBytes 関数によって以前に作成されたストレージ オブジェクトを再読み込みできます。 メモリ ハンドルとその内容は、新しいバイト配列オブジェクトの作成によって妨げされません。

バイト配列の初期サイズは、GlobalSize 関数によって返される hGlobal のサイズです。 これは、丸めのためにハンドルに最初に割り当てられたサイズと必ずしも同じではありません。 バイト配列の論理サイズが重要な場合は、 CreateILockBytesOnHGlobal の呼び出しに従い、 ILockBytes::SetSize を呼び出します。

CreateStreamOnHGlobal を使用してバイト配列オブジェクトを作成した後、StgCreateDocfileOnILockBytes を使用してメモリ内に新しいストレージ オブジェクトを作成するか、StgOpenStorageOnILockBytes を使用して、メモリ ブロックに既に含まれている既存のストレージ オブジェクトを再度開くことができます。 GetHGlobalFromILockBytes を呼び出して、バイト配列オブジェクトに関連付けられているメモリ ハンドルを取得できます。

メモリ ハンドルが CreateILockBytesOnHGlobal に渡される場合、または GetHGlobalFromILockBytes が呼び出された場合、この関数のメモリ ハンドルは、バイト配列オブジェクトによって引き続き使用されている間に、呼び出し元から直接アクセスできます。 この機能とその影響を使用する場合は、適切な注意が必要です。

  • バイト配列オブジェクトの有効期間中は 、hGlobal メモリ ハンドルを解放しないでください。 メモリ ハンドルを解放する前に、ILockBytes::Release を呼び出す必要があります。
  • GlobalReAlloc を呼び出して、バイト配列オブジェクトの有効期間中にメモリ ハンドルのサイズを変更しないでください。 これにより、アプリケーションのクラッシュやメモリの破損が発生する可能性があります。 ILockBytes::WriteAt メソッドと ILockBytes::SetSize メソッドは GlobalReAlloc を内部的に呼び出す可能性があるため、同じメモリ ハンドルに複数のバイト配列オブジェクトを作成しないでください。
  • 可能な場合は、バイト配列オブジェクトの有効期間中にメモリ ブロックにアクセスしないようにします。これは、オブジェクトが内部的に GlobalReAlloc を呼び出し、そのサイズと位置を前提としないためです。 メモリ ブロックにアクセスする必要がある場合は、メモリ アクセス呼び出しを GlobalLockGlobalUnLock の呼び出しで囲む必要があります。
  • メモリ ハンドルが GlobalLock でロックされている間は、オブジェクトのメソッドを呼び出さないようにします。 これにより、メソッド呼び出しが予期しない失敗する可能性があります。
呼び出し元が fDeleteOnRelease パラメーターを FALSE に設定した場合、呼び出し元は最終リリース後に hGlobal も解放する必要があります。 呼び出し元が fDeleteOnRelease パラメーターを TRUE に設定した場合、最終リリースでは hGlobal が自動的に解放されます。 hGlobal パラメーターとして渡されるメモリ ハンドルは、次の例に示すように、移動可能で非カード可能として割り当てる必要があります。
HGLOBAL	hMem = ::GlobalAlloc(GMEM_MOVEABLE,iSize);
if (!hMem)
    AfxThrowMemoryException();

LPVOID pCompoundFile = ::GlobalLock(hMem);
... // Fill memory
::GlobalUnlock(hMem);

CComPtr<ILockBytes> spLockBytes;
HRESULT hr = ::CreateILockBytesOnHGlobal(hMem,FALSE,&spLockBytes);


CreateILockBytesOnHGlobal、GMEM_FIXEDで割り当てられたメモリを受け入れますが、この使用はお勧めしません。 GMEM_FIXEDで割り当てられた HGLOBAL は実際には処理されず、再割り当て時に値が変更される可能性があります。 メモリ ハンドルが GMEM_FIXED で割り当てられ、 fDeleteOnReleaseFALSE の場合、呼び出し元は GetHGlobalFromILockBytes を 呼び出して、ハンドルを解放するために正しい HGLOBAL 値を取得する必要があります。

この ILockBytes の実装では、リージョンのロックはサポートされていません。 StgCreateDocfileOnILockBytes 関数または StgOpenStorageOnILockBytes 関数でこの実装を使用するアプリケーションでは、同じ ILockBytes オブジェクトで複数の同時実行インスタンスを開かないようにする必要があります。

Windows 7 および Windows Server 2008 R2 より前では、 GlobalReAlloc を呼び出してメモリ ブロックを拡張するときに、この実装ではメモリがゼロになりませんでした。 ILockBytes::SetSize を使用してバイト配列のサイズを大きくするか、バイト配列の現在の末尾を超える場所に書き込むことで、新しく割り当てられたメモリの書き込まれていない部分は初期化されません。 StgCreateDocfileOnILockBytesStgOpenStorageOnILockBytes によって返されるストレージ オブジェクトは、新しく割り当てられたすべての領域を初期化せずにバイト配列のサイズを大きくする可能性があります。

メモリ内の複合ファイルは、通常、スクラッチ領域として、またはストレージ オブジェクトを必要とする API で使用されます。このような場合、初期化されていないメモリは一般に問題になりません。 ただし、メモリ ブロックの内容がファイルに書き込まれる場合は、情報漏えいの可能性を回避するために、次の代替手段を検討してください。

  • メモリ ブロックの内容を直接書き込むのではなく、 IStorage::CopyTo メソッドを使用して、メモリ内複合ファイルの論理内容をコピー先ファイルにコピーします。
  • メモリ内の複合ファイルの代わりに、pwcsName パラメーターに NULL 値を指定して StgCreateStorageEx を呼び出して一時ファイルを作成します。 宛先ファイルに書き込むときは、 IRootStorage::SwitchToFile メソッドを 使用します。
  • メモリの再割り当てがゼロになるように ILockBytes インターフェイスを実装します (たとえば、HeapReAllocHEAP_ZERO_MEMORY フラグを参照してください)。 その後、このバイト配列のメモリ内容をファイルに書き込むことができます。

要件

要件
サポートされている最小のクライアント Windows 2000 Professional [デスクトップ アプリ |UWP アプリ]
サポートされている最小のサーバー Windows 2000 Server [デスクトップ アプリ |UWP アプリ]
対象プラットフォーム Windows
ヘッダー coml2api.h (Ole2.h を含む)
Library Ole32.lib
[DLL] Ole32.dll

こちらもご覧ください

GetHGlobalFromILockBytes

ILockBytes

StgOpenStorageOnILockBytes