-1

我正在尝试使用 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(),我该如何解决这个问题?

4

1 回答 1

1

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

另请注意,CString它基于TCHAR,它映射到charwchar_t取决于您是为 ANSI/MBCS 还是 Unicode 编译项目。因此,只有在以下情况下,才能从流中直接读取到 aCString中才能正常工作:

  1. 流包含 ANSI 字符并TCHAR映射到char.

  2. 流包含 UTF-16 字符并TCHAR映射到wchar_t.

如果流的字符类型CString与.TCHARCString

尝试更多类似的东西:

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;
}
于 2018-01-26T02:02:07.013 回答