如何将OLE IStorage转换为字节数组或IStream(C++ WINAPI)
将OLE IStorage转换为内存IStream及字节数组的实现方案
核心思路是利用内存IStream作为中间载体,通过IStorage::Save方法将存储内容直接写入内存流,完全规避磁盘IO,之后即可从内存流提取字节数组。以下是具体实现步骤和代码:
步骤说明
- 创建内存-backed的
IStream对象:用CreateStreamOnHGlobal创建基于全局内存的流,无需依赖磁盘文件。 - 序列化IStorage到内存流:调用
IStorage::Save,把存储的所有元素写入内存流。 - 提取字节数组:重置流指针到起始位置,获取流大小后分配内存,读取全部内容到字节数组。
代码实现
#include <windows.h> #include <ole2.h> #include <vector> // 将IStorage转换为字节数组 HRESULT IStorageToByteArray(IStorage* pStorage, std::vector<BYTE>& outBytes) { if (!pStorage) return E_INVALIDARG; IStream* pMemStream = nullptr; HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, &pMemStream); if (FAILED(hr)) return hr; // 将IStorage内容写入内存流 hr = pStorage->Save(pMemStream, STGFMT_STORAGE, 0); if (SUCCEEDED(hr)) { // 重置流指针到起始位置 LARGE_INTEGER liZero = {0}; hr = pMemStream->Seek(liZero, STREAM_SEEK_SET, NULL); if (SUCCEEDED(hr)) { // 获取流的总大小 STATSTG stat = {0}; hr = pMemStream->Stat(&stat, STATFLAG_NONAME); if (SUCCEEDED(hr) && stat.cbSize.QuadPart > 0) { // 分配内存并读取全部内容 outBytes.resize(static_cast<size_t>(stat.cbSize.QuadPart)); ULONG bytesRead = 0; hr = pMemStream->Read(outBytes.data(), static_cast<ULONG>(stat.cbSize.QuadPart), &bytesRead); } } } // 释放COM对象 if (pMemStream) pMemStream->Release(); return hr; }
关键细节说明
CreateStreamOnHGlobal的第二个参数传TRUE,表示流释放时自动释放关联的全局内存,无需手动管理内存资源。IStorage::Save的STGFMT_STORAGE参数指定保存格式为标准OLE存储格式,确保内容能被后续正确解析。- 所有COM调用必须检查
HRESULT返回值,避免空指针、无效操作等问题。 - 得到的
std::vector<BYTE>可直接用于进程间传递,或通过WriteFile写入文件,无需额外转换。
额外提示
如果需要直接获取IStream对象供后续流程使用,只需在Save完成后重置流指针,返回pMemStream即可(注意调用方需负责调用Release释放该COM对象)。
内容的提问来源于stack exchange,提问作者LUN
相关产品推荐
相关产品推荐

