VC中如何将数组转换为IStream流对象?
VC中如何将数组转换为IStream流对象?
我目前的方法:
创建全局内存,将数组内容拷贝到全局内存,再使用全局内存创建流(在VC中我只知道一个CreateStreamOnHGlobal()函数,惭愧!).这样虽然能达到目的,但是存在一个这样的问题:数组存在两个拷贝,一个是原来的数组本身,二个是全局内存里的拷贝.
我的问题是:怎样使用数组本身直接创建流,是流直接指向源数组呢?别告诉我换成Java,或者.Net哦,换了我就没有问题了,哈哈.
期待您的回复!
[解决办法]
- C/C++ code
// CVFStream
CVFStream::CVFStream()
{
m_filehand = NULL;
}
HRESULT CVFStream::FinalConstruct()
{
return S_OK;
}
void CVFStream::FinalRelease()
{
if( m_filehand != NULL && m_filehand != INVALID_HANDLE_VALUE)
{
CloseHandle(m_filehand);
}
}
void CVFStream::SetServPath(const std::string& path)
{
m_servpath = path;
}
HRESULT CVFStream::Read(void *pv, ULONG cb, ULONG *pcbRead)
{
if(m_filehand == NULL)
{
m_filehand = OpenServFile(m_servpath);
}
if(m_filehand == INVALID_HANDLE_VALUE)
{
*pcbRead = 0;
return S_FALSE;
}
DWORD copyed;
if(!ReadFile(m_filehand, pv, cb, ©ed, NULL))
{
return GetLastError();
}
if(copyed < cb)
{
CloseHandle(m_filehand);
m_filehand = INVALID_HANDLE_VALUE;
}
if(pcbRead != NULL)
{
(*pcbRead) = copyed;
}
return S_OK;
}
HRESULT CVFStream::Write(void const *pv, ULONG cb, ULONG *pcbWritten)
{
return E_ACCESSDENIED;
}
HRESULT CVFStream::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
{
return E_NOTIMPL;
}
HRESULT CVFStream::SetSize(ULARGE_INTEGER libNewSize)
{
return E_ACCESSDENIED;
}
HRESULT CVFStream::CopyTo(IStream *pstm, ULARGE_INTEGER cb,
ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
{
return E_NOTIMPL;
}
HRESULT CVFStream::Commit(DWORD grfCommitFlags)
{
return E_NOTIMPL;
}
HRESULT CVFStream::Revert(void)
{
return E_NOTIMPL;
}
HRESULT CVFStream::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
return E_NOTIMPL;
}
HRESULT CVFStream::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
return E_NOTIMPL;
}
HRESULT CVFStream::Stat(STATSTG *pstatstg, DWORD grfStatFlag)
{
return E_NOTIMPL;
}
HRESULT CVFStream::Clone(IStream **ppstm)
{
return E_NOTIMPL;
}
HANDLE CVFStream::OpenServFile(const std::string& path)
{
std::string localpath = theCmd::Instance().GetLocalMapFile(path);
CA2T tlocalpath(localpath.c_str());
return CreateFile(tlocalpath, FILE_READ_DATA, FILE_SHARE_READ,
NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
}