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의 크기입니다. 반올림으로 인해 핸들에 대해 원래 할당된 크기와 반드시 같은 크기는 아닙니다. 바이트 배열의 논리적 크기가 중요한 경우 ILockBytes::SetSize를 호출하여 CreateILockBytesOnHGlobal 호출을 따릅니다.
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 할당된 HGLOBAL은 실제로 처리되지 않으며 재할당 시 해당 값이 변경될 수 있습니다. 메모리 핸들이 GMEM_FIXED 할당되고 fDeleteOnRelease 가 FALSE인 경우 호출자는 GetHGlobalFromILockBytes 를 호출하여 핸들을 해제하기 위해 올바른 HGLOBAL 값을 가져와야 합니다.
이 ILockBytes 구현은 지역 잠금을 지원하지 않습니다. StgCreateDocfileOnILockBytes 또는 StgOpenStorageOnILockBytes 함수와 함께 이 구현을 사용하는 애플리케이션은 동일한 ILockBytes 개체에서 여러 동시 인스턴스를 열지 않아야 합니다.
Windows 7 및 Windows Server 2008 R2 이전에는 GlobalReAlloc 을 호출하여 메모리 블록을 확장할 때 이 구현에서 메모리가 0이 되지 않았습니다. ILockBytes::SetSize를 사용하여 바이트 배열의 크기를 늘리거나 바이트 배열의 현재 끝을 지나 위치에 쓰면 새로 할당된 메모리의 기록되지 않은 부분이 초기화되지 않습니다. StgCreateDocfileOnILockBytes 및 StgOpenStorageOnILockBytes에서 반환된 스토리지 개체는 새로 할당된 공간을 모두 초기화하지 않고 바이트 배열의 크기를 늘릴 수 있습니다.
메모리의 복합 파일은 일반적으로 스토리지 개체가 필요한 스크래치 공간 또는 API와 함께 사용되며, 이러한 경우 초기화되지 않은 메모리는 일반적으로 문제가 되지 않습니다. 그러나 메모리 블록의 내용이 파일에 기록되는 경우 잠재적인 정보 공개를 방지하기 위해 다음 대안을 고려합니다.
- 메모리 블록의 내용을 직접 작성하는 대신 IStorage::CopyTo 메서드를 사용하여 메모리 내 복합 파일의 논리적 내용을 대상 파일에 복사합니다.
- 메모리의 복합 파일 대신 pwcsName 매개 변수에 대해 NULL 값으로 StgCreateStorageEx를 호출하여 임시 파일을 만듭니다. 대상 파일에 쓸 때 IRootStorage::SwitchToFile 메서드를 사용합니다.
- 메모리 재할당이 0이 되도록 ILockBytes 인터페이스를 구현합니다(예: HeapReAlloc의 HEAP_ZERO_MEMORY 플래그 참조). 그런 다음 이 바이트 배열의 메모리 내용을 파일에 쓸 수 있습니다.
요구 사항
요구 사항 | 값 |
---|---|
지원되는 최소 클라이언트 | Windows 2000 Professional [데스크톱 앱 | UWP 앱] |
지원되는 최소 서버 | Windows 2000 Server [데스크톱 앱 | UWP 앱] |
대상 플랫폼 | Windows |
헤더 | coml2api.h(Ole2.h 포함) |
라이브러리 | Ole32.lib |
DLL | Ole32.dll |