createStreamOnHGlobal 函数 (combaseapi.h)

CreateStreamOnHGlobal 函数创建一个流对象,该对象使用 HGLOBAL 内存句柄来存储流内容。 此对象是 OLE 提供的 IStream 接口实现。

返回的流对象支持读取和写入,不支持事务处理,并且不支持区域锁定。 对象调用 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
Library Ole32.lib
DLL Ole32.dll

另请参阅

GetHGlobalFromStream

IStream - 复合文件实现

IStream::SetSize

InMemoryRandomAccessStream