开发者

Do without USES_CONVERSION macro

开发者 https://www.devze.com 2023-01-04 12:46 出处:网络
I have this code that uses the USE_CONVERSION macro in a C++ project... I was wondering if this is written well, (not written by me), and if there\'s any better ways to do it, without the USES_CONVERS

I have this code that uses the USE_CONVERSION macro in a C++ project...

I was wondering if this is written well, (not written by me), and if there's any better ways to do it, without the USES_CONVERSION and W2A macros.

STDMETHODIMP CInterpreter::GetStringVar(BSTR bstrNamespace, BSTR bstrVar, BSTR *pbstrValue)
{
USES_CONVERSION;

try
{
    if (!pbstrValue) return E_POINTER;

    char* pszNamespace= W2A(_bstr_t(bstrNamespace).operator wchar_t*());
    char* pszVar= W2A(_bstr_t(bstrVar).operator wchar_t*());  // Is this not better done another way????
    
    char pszErrStr[kPYTHONERRBUFSIZE];
    char pszStrValue[kPYTHONSTRVALUESIZE];
    BOOL bResult= Python_GetStringVar(pszNamespace, pszVar, pszErrStr, pszStrValue, kPYTHONSTRVALUESIZE);

    *pbstrValue= _bstr_t(pszStrValue).operator BSTR();

    if (!bRe开发者_开发知识库sult)
        throw x::internal_error(A2W(pszErrStr));

    return S_OK;
}
}


There is the class-based ATL::CA2W and friends (in atlconv.h, I believe) that don't put the string on the stack and don't use macros. You don't need a USES_CONVERSION in the function:

throw x::internal_error(ATL::CA2W(pszErrStr));

Also, since your arguments are BSTR (wchar_t *), you don't need to convert them to _bstr_t.

NOTE: The lifetime of the converted string is the lifetime of the CW2A object, so you will need to put it into a string class, e.g.:

CStringA arg = CW2A(bstrArg);

NOTE 2: pbstrValue is an output value. The _bstr_t instance will destroy the memory allocated for the BSTR. Therefore, you need to either use SysAllocString directly, or detach the BSTR:

pbstrValue = SysAllocString(CA2W(retval));

or:

pbstrValue = CComBSTR(CA2W(retval)).Detach();

NOTE 3: Explicit use of the conversion operators (.operator BSTR()) is not needed -- the compiler will call the correct one for you.

NOTE 4: Since this looks like a COM call, you really do not want to be throwing a C++ exception. You probably want to set an IErrorInfo object (probably with a helper):

if (!bResult) { SetError(CA2W(errorStr)); return E_FAIL; }

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号