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::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; }