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_INVALIDARG 和 E_OUTOFMEMORY,以及下列各項:
備註
如果 hGlobal 為 NULL,CreateILockBytesOnHGlobal 會配置新的記憶體句柄,而且位元組陣列一開始是空的。
如果 hGlobal 不是 NULL,位元組陣組物件的初始內容就是記憶體區塊的目前內容。 因此,此函式可用來在記憶體中開啟現有的位元組數位,例如重載 先前由 StgCreateDocfileOnILockBytes 函式建立的記憶體物件。 建立新的位元組陣列物件時,記憶體句柄及其內容會不受干擾。
位元組陣列的初始大小是 GlobalSize 函式所傳回的 hGlobal 大小。 這不一定是原本為句柄配置的相同大小,因為四捨五入。 如果位元組陣列的邏輯大小很重要,請遵循呼叫 CreateILockBytesOnHGlobal 並呼叫 ILockBytes::SetSize。
使用 CreateStreamOnHGlobal 建立位元組數位對象之後, StgCreateDocfileOnILockBytes 可用來在記憶體中建立新的儲存物件,或者可以使用 StgOpenStorageOnILockBytes 重新開啟先前包含在記憶體區塊中的儲存物件。 您可以呼叫 GetHGlobalFromILockBytes 來擷取與位元組數位對象相關聯的記憶體句柄。
如果記憶體句柄傳遞至 CreateILockBytesOnHGlobal 或 呼叫 GetHGlobalFromILockBytes ,則呼叫端仍然可以直接存取此函式的記憶體句柄,而呼叫端仍在位元組數位物件使用中。 應謹慎使用這項功能及其含意:
- 請勿在位元組數位物件的存留期內釋放 hGlobal 記憶體句柄。 在釋放記憶體句柄之前,必須先呼叫 ILockBytes::Release。
- 請勿呼叫 GlobalReAlloc ,在位元組數位物件的存留期內變更記憶體句柄的大小。 這可能會造成應用程式當機或記憶體損毀。 請避免在同一個記憶體句柄上建立多個字節陣列物件,因為 ILockBytes::WriteAt 和 ILockBytes::SetSize 方法可能會在內部呼叫 GlobalReAlloc。
- 可能的話,請避免在位元組數位物件的存留期記憶體取記憶體區塊,因為物件可能會在內部呼叫 GlobalReAlloc ,而且不會假設其大小和位置。 如果必須存取記憶體區塊,記憶體存取呼叫應以 GlobalLock 和 GlobalUnLock 的呼叫括住。
- 避免在記憶體句柄使用 GlobalLock 鎖定時呼叫物件的 方法。 這可能會導致方法呼叫無法預測。
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且fDeleteOnRelease 為 FALSE,則呼叫端必須呼叫 GetHGlobalFromILockBytes 以取得正確的 HGLOBAL 值,才能釋放句柄。
此 ILockBytes 實作不支援區域鎖定。 搭配 StgCreateDocfileOnILockBytes 或 StgOpenStorageOnILockBytes 函式使用這個實作的應用程式應該避免在同一 個 ILockBytes 對象上開啟多個並行實例。
在 Windows 7 和 Windows Server 2008 R2 之前,呼叫 GlobalReAlloc 以增加記憶體區塊時,此實作不會為零記憶體。 使用 ILockBytes::SetSize 增加位元組陣列的大小,或寫入到超過位元組陣列目前結尾的位置,將會保留新配置記憶體未初始化的任何未寫入部分。 StgCreateDocfileOnILockBytes 和 StgOpenStorageOnILockBytes 所傳回的儲存物件可能會增加位元組陣列的大小,而不需要初始化所有新配置的空間。
記憶體中的複合檔案通常用來作為臨時空間或需要儲存物件的 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 |