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 (!bResult)
throw x::internal_error(A2W(pszErrStr));
return S_OK;
}
}
There is the class-based
ATL::CA2Wand friends (inatlconv.h, I believe) that don’t put the string on the stack and don’t use macros. You don’t need aUSES_CONVERSIONin 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
CW2Aobject, so you will need to put it into a string class, e.g.:CStringA arg = CW2A(bstrArg);NOTE 2:
pbstrValueis an output value. The_bstr_tinstance will destroy the memory allocated for theBSTR. Therefore, you need to either useSysAllocStringdirectly, or detach theBSTR: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
IErrorInfoobject (probably with a helper):if (!bResult) { SetError(CA2W(errorStr)); return E_FAIL; }