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인 경우 함수는 새 메모리 핸들을 할당하고 스트림은 처음에 비어 있습니다.

hGlobalNULL이 아닌 경우 스트림의 초기 콘텐츠는 메모리 블록의 현재 콘텐츠입니다. 따라서 CreateStreamOnHGlobal 을 사용하여 메모리에서 기존 스트림을 열 수 있습니다. 메모리 핸들과 해당 콘텐츠는 새 스트림 개체를 만들어 방해받지 않습니다.

스트림의 초기 크기는 GlobalSize 함수에서 반환한 hGlobal의 크기입니다. 반올림으로 인해 핸들에 대해 원래 할당된 크기가 반드시 같은 것은 아닙니다. 스트림의 논리적 크기가 중요한 경우 IStream::SetSize 메서드를 호출하여 이 함수에 대한 호출을 따릅니다.

새 스트림 개체의 초기 검색 위치는 스트림의 시작 위치입니다.

CreateStreamOnHGlobal을 사용하여 스트림 개체를 만든 후 GetHGlobalFromStream을 호출하여 스트림 개체와 연결된 메모리 핸들을 검색합니다.

메모리 핸들이 CreateStreamOnHGlobal 에 전달되거나 GetHGlobalFromStream 이 호출되는 경우 스트림 개체에서 계속 사용하는 동안 호출자가 이 함수의 메모리 핸들에 직접 액세스할 수 있습니다. 이 기능 및 해당 의미를 사용할 때 적절한 주의를 기울여야 합니다.

  • 스트림 개체의 수명 동안 hGlobal 메모리 핸들을 해제하지 마세요. 메모리 핸들을 해제하기 전에 IStream::Release를 호출해야 합니다.
  • GlobalReAlloc을 호출하여 스트림 개체 또는 해당 클론의 수명 동안 메모리 핸들의 크기를 변경하지 마세요. 이로 인해 애플리케이션 크래시 또는 메모리 손상이 발생할 수 있습니다. IStream::Write 및 IStream::SetSize 메서드가 내부적으로 GlobalReAlloc을 호출할 수 있으므로 동일한 메모리 핸들에서 여러 스트림 개체를 별도로 만들지 마십시오. IStream::Clone 메서드를 사용하여 원래 스트림 개체와의 액세스를 올바르게 조정하는 동일한 메모리 핸들을 기반으로 새 스트림 개체를 만들 수 있습니다.
  • 가능하면 개체가 내부적으로 GlobalReAlloc 을 호출할 수 있고 해당 크기와 위치를 가정하지 않으므로 스트림 개체의 수명 동안 메모리 블록에 액세스하지 마세요. 메모리 블록에 액세스해야 하는 경우 메모리 액세스 호출은 GlobalLock 및 GlobalUnLock 호출로 묶어야 합니다.
  • 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);

CreateStreamOnHGlobalGMEM_FIXED 할당된 메모리 핸들을 수락하지만 이 사용법은 권장되지 않습니다. GMEM_FIXED 할당된 HGLOBAL은 실제로 처리되지 않으며 재할당 시 해당 값이 변경될 수 있습니다. 메모리 핸들이 GMEM_FIXED 할당되었고 fDeleteOnReleaseFALSE인 경우 호출자는 GetHGlobalFromStream 을 호출하여 올바른 핸들을 가져와야 합니다.

Windows 7 및 Windows Server 2008 R2 이전에는 GlobalReAlloc 을 호출하여 메모리 블록을 확장할 때 이 구현에서 메모리가 0이 되지 않았습니다. IStream::SetSize를 사용하거나 스트림의 현재 끝을 지나 위치에 기록하여 스트림의 크기를 늘리면 새로 할당된 메모리의 일부가 초기화되지 않을 수 있습니다.

요구 사항

   
지원되는 최소 클라이언트 Windows 2000 Professional [데스크톱 앱 | UWP 앱]
지원되는 최소 서버 Windows 2000 Server [데스크톱 앱 | UWP 앱]
대상 플랫폼 Windows
헤더 combaseapi.h
라이브러리 Ole32.lib
DLL Ole32.dll

추가 정보

GetHGlobalFromStream

IStream - 복합 파일 구현

IStream::SetSize

InMemoryRandomAccessStream