【问题标题】:LPSTREAM unable to read into CStringLPSTREAM 无法读入 CString
【发布时间】:2018-01-26 00:43:49
【问题描述】:

我正在尝试使用 LPSTREAM 将文本读入 CString,但它似乎无法正常工作,这是我正在调用的代码:

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(),我该如何解决这个问题?

【问题讨论】:

  • ULONG read = 0; hrRet = lpSrc->Read(myCStr->GetBuffer(size), size, &read); myCStr->ReleaseBuffer(read); 类似的东西。

标签: c++ stream storage compound-file


【解决方案1】:

主要问题是你传递了一个错误的指针到Read()。您传递的是myCStr 参数本身的内存地址,而不是指向CString 的地址,或者更准确地说,是CString 拥有的字符缓冲区的内存地址。代码编译只是因为Read() 将简单的void* 指针指向缓冲区,并且any 指针可隐式转换为void*

还请注意,CString 基于 TCHAR,它映射到 charwchar_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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-13
    • 1970-01-01
    • 1970-01-01
    • 2012-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-06
    相关资源
    最近更新 更多