Функция CreateStreamOnHGlobal (combaseapi.h)
Функция CreateStreamOnHGlobal создает объект потока, который использует дескриптор памяти HGLOBAL для хранения содержимого потока. Этот объект является реализацией интерфейса IStream , предоставляемой OLE.
Возвращаемый объект потока поддерживает как чтение, так и запись, не выполняет транзакции и не поддерживает блокировку региона. Объект вызывает функцию GlobalReAlloc для увеличения блока памяти по мере необходимости.
Синтаксис
HRESULT CreateStreamOnHGlobal(
[in] HGLOBAL hGlobal,
[in] BOOL fDeleteOnRelease,
[out] LPSTREAM *ppstm
);
Параметры
[in] hGlobal
Дескриптор памяти, выделенный функцией GlobalAlloc , или, если значение NULL , выделяется новый дескриптор. Дескриптор должен быть выделен как перемещаемый и неразглавный.
[in] fDeleteOnRelease
Значение типа , указывающее, должен ли базовый дескриптор этого объекта потока автоматически освобождаться при освобождении объекта потока. Если задано значение FALSE, вызывающий объект должен освободить hGlobal после окончательного выпуска. Если задано значение TRUE, окончательный выпуск автоматически освободит базовый дескриптор. Дополнительные сведения о случае, когда fDeleteOnRelease имеет значение FALSE, см. в примечаниях.
[out] ppstm
Адрес переменной указателя IStream*, которая получает указатель интерфейса на новый объект потока. Его значение не может быть NULL.
Возвращаемое значение
Эта функция поддерживает стандартные возвращаемые значения E_INVALIDARG и E_OUTOFMEMORY, а также следующие.
Комментарии
Если hGlobal имеет значение NULL, функция выделяет новый дескриптор памяти, и поток изначально пуст.
Если hGlobal не равно NULL, начальное содержимое потока является текущим содержимым блока памяти. Таким образом, createStreamOnHGlobal можно использовать для открытия существующего потока в памяти. Дескриптор памяти и его содержимое не нарушаются при создании нового объекта потока.
Начальный размер потока — это размер hGlobal , возвращаемый функцией GlobalSize . Из-за округления это не обязательно тот же размер, который был изначально выделен для дескриптора. Если важен логический размер потока, выполните вызов этой функции с вызовом метода IStream::SetSize .
Начальная позиция поиска нового объекта потока является началом потока.
После создания объекта потока с помощью CreateStreamOnHGlobal вызовите Метод GetHGlobalFromStream , чтобы получить дескриптор памяти, связанный с объектом потока.
Если дескриптор памяти передается в CreateStreamOnHGlobal или вызывается метод GetHGlobalFromStream , вызывающий объект может напрямую обращаться к дескриптору памяти этой функции, пока он все еще используется объектом потока. Следует проявлять соответствующую осторожность при использовании этой возможности и ее последствиях:
- Не освобождайте дескриптор памяти hGlobal в течение времени существования объекта потока. IStream::Release необходимо вызвать перед освобождением дескриптора памяти.
- Не вызывайте GlobalReAlloc для изменения размера дескриптора памяти в течение времени существования объекта потока или его клонов. Это может привести к сбоям приложения или повреждению памяти. Избегайте создания нескольких объектов потока по отдельности в одном дескрипторе памяти, так как методы IStream::Write и IStream::SetSize могут вызывать GlobalReAlloc. Метод IStream::Clone можно использовать для создания нового объекта потока на основе того же дескриптора памяти, который будет правильно координировать доступ к исходному объекту потока.
- По возможности избегайте доступа к блоку памяти в течение времени существования объекта потока, так как объект может вызывать GlobalReAlloc и не делать предположений о его размере и расположении. Если требуется доступ к блоку памяти, вызовы доступа к памяти должны быть окружены вызовами GlobalLock и GlobalUnLock.
- Избегайте вызова методов объекта, пока дескриптор памяти заблокирован с помощью GlobalLock. Это может привести к непредсказуемой ошибке вызовов методов.
Дескриптор памяти, переданный в качестве параметра 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, но это использование не рекомендуется. HGLOBALs, выделенные с помощью GMEM_FIXED , на самом деле не являются дескрипторами, и их значение может измениться при перераспределении. Если дескриптор памяти был выделен с помощью GMEM_FIXED а fDeleteOnRelease имеет значение FALSE, вызывающий объект должен вызвать GetHGlobalFromStream , чтобы получить правильный дескриптор, чтобы освободить его.
До Windows 7 и Windows Server 2008 R2 эта реализация не обнуляла память при вызове GlobalReAlloc для увеличения блока памяти. Увеличение размера потока с помощью IStream::SetSize или путем записи в расположение после текущего конца потока может оставить части вновь выделенной памяти неинициализированными.
Требования
Минимальная версия клиента | Windows 2000 Профессиональная [классические приложения | Приложения UWP] |
Минимальная версия сервера | Windows 2000 Server [классические приложения | Приложения UWP] |
Целевая платформа | Windows |
Header | combaseapi.h |
Библиотека | Ole32.lib |
DLL | Ole32.dll |