Обойдитесь без макроса USES_CONVERSION

У меня есть этот код, который использует макрос USE_CONVERSION в проекте C++...

Я задавался вопросом, записано ли это хорошо, (не записанный мной), и если существуют любые лучшие способы сделать это без USES_CONVERSION и макросов W2A.

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 (!bResult)
        throw x::internal_error(A2W(pszErrStr));

    return S_OK;
}
}
5
задан Tony The Lion 22 June 2010 в 07:51
поделиться

1 ответ

Есть основанный на классах ATL::CA2W и друзья (в atlconv.h, я полагаю), которые не кладут строку в стек и не используют макросы. Вам не нужна USES_CONVERSION в функции:

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

Также, поскольку ваши аргументы являются BSTR (wchar_t *), вам не нужно преобразовывать их в _bstr_t.

ПРИМЕЧАНИЕ: Время жизни преобразованной строки - это время жизни объекта CW2A, поэтому вам нужно поместить ее в класс string, например:

CStringA arg = CW2A(bstrArg);

ПРИМЕЧАНИЕ 2: pbstrValue - это выходное значение. Экземпляр _bstr_t уничтожит память, выделенную для BSTR. Поэтому нужно либо использовать SysAllocString напрямую, либо отсоединить BSTR:

pbstrValue = SysAllocString(CA2W(retval));

или:

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

ПРИМЕЧАНИЕ 3: Явное использование операторов преобразования (.operator BSTR()) не требуется - компилятор вызовет нужный за вас.

ПРИМЕЧАНИЕ 4: Поскольку это похоже на вызов COM, вы не хотите бросать исключение C++. Вы, вероятно, хотите установить объект IErrorInfo (возможно, с помощником):

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

6
ответ дан 14 December 2019 в 13:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: