共用方式為


CreateStreamOnHGlobal 函式 (combaseapi.h)

CreateStreamOnHGlobal函式會建立資料流程物件,該物件會使用 HGLOBAL 記憶體控制碼來儲存資料流程內容。 這個物件是 IStream 介面的 OLE 提供實作。

傳回的資料流程物件同時支援讀取和寫入、未交易,而且不支援區域鎖定。 物件會呼叫 GlobalReAlloc 函式,視需要成長記憶體區塊。

提示 請考慮使用 SHCreateMemStream 函式來產生更好的效能,或針對 Windows 市集應用程式,請考慮使用 InMemoryRandomAccessStream
 

語法

HRESULT CreateStreamOnHGlobal(
  [in]  HGLOBAL  hGlobal,
  [in]  BOOL     fDeleteOnRelease,
  [out] LPSTREAM *ppstm
);

參數

[in] hGlobal

GlobalAlloc函式所配置的記憶體控制碼,如果為 Null,則會改為配置新的控制碼。 控制碼必須配置為可移動且不可顯示。

[in] fDeleteOnRelease

值,指出是否應該在釋放資料流程物件時自動釋放這個資料流程物件的基礎控制碼。 如果設定為 FALSE,呼叫端必須在最終版本之後釋放 hGlobal 。 如果設定為 TRUE,最終版本會自動釋放基礎控制碼。 如需 fDeleteOnReleaseFALSE案例的進一步討論,請參閱。

[out] ppstm

接收新資料流程物件介面指標的 IStream* 指標變數位址。 其值不可為 Null

傳回值

此函式支援標準傳回值E_INVALIDARG和E_OUTOFMEMORY,以及下列各項。

備註

如果 hGlobalNull,函式會配置新的記憶體控制碼,而且資料流程一開始是空的。

如果 hGlobal 不是 Null,資料流程的初始內容就是記憶體區塊的目前內容。 因此, CreateStreamOnHGlobal 可用來在記憶體中開啟現有的資料流程。 建立新的資料流程物件時,記憶體控制碼及其內容會不受干擾。

資料流程的初始大小是GlobalSize函式所傳回的hGlobal大小。 由於舍入,這不一定是原本配置給控制碼的相同大小。 如果資料流程的邏輯大小很重要,請遵循呼叫此函式並呼叫 IStream::SetSize 方法。

新資料流程物件的初始搜尋位置是資料流程的開頭。

使用 CreateStreamOnHGlobal建立資料流程物件之後,呼叫 GetHGlobalFromStream 以擷取與資料流程物件相關聯的記憶體控制碼。

如果記憶體控制碼傳遞至 CreateStreamOnHGlobal 或 呼叫 GetHGlobalFromStream ,則呼叫端仍然可以直接存取此函式的記憶體控制碼,同時資料流程物件仍在使用中。 應謹慎使用這項功能及其含意:

  • 請勿在資料流程物件的存留期間釋放 hGlobal 記憶體控制碼。 在釋放記憶體控制碼之前,必須先呼叫IStream::Release
  • 請勿呼叫 GlobalReAlloc ,以在資料流程物件或其複製品的存留期間變更記憶體控制碼的大小。 這可能會造成應用程式當機或記憶體損毀。 請避免在相同的記憶體控制碼上個別建立多個資料流程物件,因為 IStream::WriteIStream::SetSize 方法可能會在內部呼叫 GlobalReAllocIStream::Clone方法可用來根據相同的記憶體控制碼建立新的資料流程物件,以正確協調其原始資料流程物件的存取。
  • 可能的話,請避免在資料流程物件的存留期間存取記憶體區塊,因為物件可能會在內部呼叫 GlobalReAlloc ,而且不會假設其大小和位置。 如果必須存取記憶體區塊,記憶體存取呼叫應以 GlobalLockGlobalUnLock的呼叫括住。
  • 當您使用 GlobalLock鎖定記憶體控制碼時,請避免呼叫 物件的 方法。 這可能會導致方法呼叫無法預測。
如果 fDeleteOnRelease 參數為 FALSE,則呼叫端會負責釋放基礎記憶體控制碼,即使 hGlobal 參數為 Null 也一樣。 使用 GetHGlobalFromStream 函式來取得基礎記憶體控制碼,並在釋放資料流程的最後一個參考之後取得 GlobalFree 記憶體。 如果呼叫端將 fDeleteOnRelease 參數設定為 TRUE,最終版本會自動釋放基礎記憶體控制碼。

傳遞為 hGlobal 參數的記憶體控制碼必須配置為可移動和非可顯示,如下列範例所示:

HGLOBAL	hMem = ::GlobalAlloc(GMEM_MOVEABLE,iSize);
if (!hMem)
    AfxThrowMemoryException();

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

CComPtr<IStream> spStream;
HRESULT hr = ::CreateStreamOnHGlobal(hMem,FALSE,&spStream);

CreateStreamOnHGlobal 會接受配置 GMEM_FIXED的記憶體控制碼,但不建議使用此用法。 配置 GMEM_FIXED 的 HGLOBALs 並非真正處理,而且其值在重新配置時可能會變更。 如果記憶體控制碼已配置 GMEM_FIXED且fDeleteOnReleaseFALSE,則呼叫端必須呼叫 GetHGlobalFromStream 以取得正確的控制碼,才能釋放它。

在 Windows 7 和 Windows Server 2008 R2 之前,呼叫 GlobalReAlloc 以增加記憶體區塊時,此實作不會為零記憶體。 使用 IStream::SetSize 增加資料流程的大小,或寫入資料流程目前結尾之後的位置,可能會讓新配置的記憶體部分保持未初始化。

規格需求

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

另請參閱

GetHGlobalFromStream

IStream - 複合檔案實作

IStream::SetSize

InMemoryRandomAccessStream