共用方式為


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 會配置新的記憶體句柄,而且位元組陣列一開始是空的。

如果 hGlobal 不是 NULL,位元組陣組物件的初始內容就是記憶體區塊的目前內容。 因此,此函式可用來在記憶體中開啟現有的位元組數位,例如重載 先前由 StgCreateDocfileOnILockBytes 函式建立的記憶體物件。 建立新的位元組陣列物件時,記憶體句柄及其內容會不受干擾。

位元組陣列的初始大小是 GlobalSize 函式所傳回的 hGlobal 大小。 這不一定是原本為句柄配置的相同大小,因為四捨五入。 如果位元組陣列的邏輯大小很重要,請遵循呼叫 CreateILockBytesOnHGlobal 並呼叫 ILockBytes::SetSize

使用 CreateStreamOnHGlobal 建立位元組數位對象之後, StgCreateDocfileOnILockBytes 可用來在記憶體中建立新的儲存物件,或者可以使用 StgOpenStorageOnILockBytes 重新開啟先前包含在記憶體區塊中的儲存物件。 您可以呼叫 GetHGlobalFromILockBytes 來擷取與位元組數位對象相關聯的記憶體句柄。

如果記憶體句柄傳遞至 CreateILockBytesOnHGlobal 或 呼叫 GetHGlobalFromILockBytes ,則呼叫端仍然可以直接存取此函式的記憶體句柄,而呼叫端仍在位元組數位物件使用中。 應謹慎使用這項功能及其含意:

  • 請勿在位元組數位物件的存留期內釋放 hGlobal 記憶體句柄。 在釋放記憶體句柄之前,必須先呼叫 ILockBytes::Release
  • 請勿呼叫 GlobalReAlloc ,在位元組數位物件的存留期內變更記憶體句柄的大小。 這可能會造成應用程式當機或記憶體損毀。 請避免在同一個記憶體句柄上建立多個字節陣列物件,因為 ILockBytes::WriteAtILockBytes::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 的 HGLOBALs 並非真正處理,而且其值在重新配置時可能會變更。 如果記憶體句柄已配置 GMEM_FIXED且fDeleteOnReleaseFALSE,則呼叫端必須呼叫 GetHGlobalFromILockBytes 以取得正確的 HGLOBAL 值,才能釋放句柄。

ILockBytes 實作不支援區域鎖定。 搭配 StgCreateDocfileOnILockBytesStgOpenStorageOnILockBytes 函式使用這個實作的應用程式應該避免在同一 個 ILockBytes 對象上開啟多個並行實例。

在 Windows 7 和 Windows Server 2008 R2 之前,呼叫 GlobalReAlloc 以增加記憶體區塊時,此實作不會為零記憶體。 使用 ILockBytes::SetSize 增加位元組陣列的大小,或寫入到超過位元組陣列目前結尾的位置,將會保留新配置記憶體未初始化的任何未寫入部分。 StgCreateDocfileOnILockBytesStgOpenStorageOnILockBytes 所傳回的儲存物件可能會增加位元組陣列的大小,而不需要初始化所有新配置的空間。

記憶體中的複合檔案通常用來作為臨時空間或需要儲存物件的 API,在這些情況下,未初始化的記憶體通常並不相關。 不過,如果將記憶體區塊的內容寫入檔案,請考慮下列替代方案以避免潛在的資訊洩漏:

  • 使用 IStorage::CopyTo 方法,將記憶體內部複合檔案的邏輯內容複製到目的地檔案,而不是直接寫入記憶體區塊的內容。
  • 除了記憶體中的複合檔案,而是呼叫具有 pwcsName 參數 NULL 值的 StgCreateStorageEx 來建立暫存盤。 當寫入目的地檔案時,請使用 IRootStorage::SwitchToFile 方法。
  • 實作 ILockBytes 介面,讓記憶體重新分配 (請參閱 HeapReAlloc) 中的HEAP_ZERO_MEMORY旗標。 接著可以將這個位元組陣列的記憶體內容寫入檔案。

規格需求

需求
最低支援的用戶端 Windows 2000 專業版 [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows 2000 Server [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 coml2api.h (包含 Ole2.h)
程式庫 Ole32.lib
Dll Ole32.dll

另請參閱

GetHGlobalFromILockBytes

ILockBytes

StgOpenStorageOnILockBytes