LPSTREAM не может прочитать в CString

Я пытаюсь прочитать текст в CString, используя LPSTREAM, но, похоже, он работает неправильно, вот код, который я вызываю:

static HRESULT UTL_ReadStreamTxt(MyStorage* pSrcStg, const char* pszStream, CString* myCStr, int size)
{
HRESULT     hrRet = STG_E_INVALIDPARAMETER;
LPSTREAM    lpSrc = NULL;
ULONG ul;

TRY
{
USES_CONVERSION;
HRESULT hrSrc = pSrcStg->GetStg()->OpenStream(CT2COLE(strSrc),
NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE,
0,
&lpSrc);
if (hrSrc != NOERROR)
{
hrRet = hrSrc;
}
else
{
hrRet = lpSrc->Read(&myCStr, size, NULL); // Read into CString
}

}

CATCH_ALL(e)
{
hrRet = STG_E_UNKNOWN;
}
END_CATCH_ALL_AfxRelease((LPUNKNOWN*)&lpSrc);

return hrRet;
}

Когда он читает в строку, Visual Studio говорит, что данные в CString повреждены.

Содержимое потока составного хранилища следующее:

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz

Я не совсем уверен, что я правильно использую Read (). Как мне решить эту проблему?

-1

Решение

Основная проблема в том, что вы передаете неверный указатель на Read(), Вы передаете адрес памяти myCStr сам параметр, а не адрес CString или, более точно, адрес памяти символьного буфера, который CString владеет. Код компилируется только потому, что Read() занимает простое void* указатель на буфер и любой указатель неявно преобразуется в void*,

Также обратите внимание, что CString основывается на TCHAR, который отображается либо char или же wchar_t в зависимости от того, компилируете ли вы свой проект для ANSI / MBCS или Unicode. Таким образом, чтение из потока прямо в CString будет работать правильно только если:

  1. поток содержит символы ANSI и TCHAR карты для char,

  2. поток содержит символы UTF-16 и TCHAR карты для wchar_t,

Если тип символа потока не соответствует типу символа, используемому CStringВы должны сначала прочитать поток в промежуточный буфер, а затем преобразовать его в TCHAR прежде чем он может быть сохранен в CString,

Попробуйте что-то вроде этого:

static HRESULT UTL_ReadStreamTxt(MyStorage* pSrcStg, const char* pszStream, CString* myCStr, int size)
{
HRESULT     hrRet = STG_E_INVALIDPARAMETER;
LPSTREAM    lpSrc = NULL;
ULONG       ul;
LPVOID      buffer;

TRY
{
USES_CONVERSION;
HRESULT hrSrc = pSrcStg->GetStg()->OpenStream(CT2COLE(strSrc),
NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE,
0,
&lpSrc);
if (hrSrc != S_OK)
{
hrRet = hrSrc;
}
else
{
// if the stream's character type matches TCHAR...

buffer = myCStr->GetBuffer(size / sizeof(TCHAR));
hrRet = lpSrc->Read(buffer, size, &ul);
myCStr->ReleaseBuffer(ul / sizeof(TCHAR));

// else, if the stream's character type is 'char' and TCHAR is 'wchar_t'...

CStringA tmp;
buffer = tmp.GetBuffer(size);
hrRet = lpSrc->Read(buffer, size, &ul);
tmp.ReleaseBuffer(ul);
*myCStr = CString((LPSTR)tmp, tmp.GetLength());

// else, if the stream's character type is 'wchar_t' and TCHAR is 'char'...

CStringW tmp;
buffer = tmp.GetBuffer(size / sizeof(wchar_t));
hrRet = lpSrc->Read(buffer, size, &ul);
tmp.ReleaseBuffer(ul / sizeof(wchar_t));
*myCStr = CString((LPWSTR)tmp, tmp.GetLength());

// alternatively, you can do the above 2 cases more generically...

typedef CStringT<char or wchar_t> CStreamString;
CStreamString tmp;
buffer = tmp.GetBuffer(size / sizeof(CStreamString::XCHAR));
hrRet = lpSrc->Read(buffer, size, &ul);
tmp.ReleaseBuffer(ul / sizeof(CStreamString::XCHAR));
*myCStr = CString((CStreamString::PXSTR)tmp, tmp.GetLength());
}
}

CATCH_ALL(e)
{
hrRet = STG_E_UNKNOWN;
}
END_CATCH_ALL

_AfxRelease((LPUNKNOWN*)&lpSrc);

return hrRet;
}
1

Другие решения

Других решений пока нет …