2010-06-22 55 views
4

我有这样的代码,使用USE_CONVERSION宏在C++项目...做不USES_CONVERSION宏观

如果写得好,(不是我写的),我想知道是否有任何更好的方法这样做,没有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; 
} 
} 
+0

由于也有一个BSTR,它看起来像微软的MFC/ATL的东西。请相应标记。 – MSalters 2010-06-22 07:50:39

+0

BSTR是一个Win32(平台SDK)类型。 _bstr_t也是Platform SDK的一部分(它被#import使用)。 – reece 2012-11-27 00:38:49

回答

5

有基于类的ATL :: CA2W和朋友(在atlconv.h,我相信)不要把字符串在栈上,不要使用宏。你并不需要一个USES_CONVERSION的功能:

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

而且,由于你的论点是BSTR(wchar_t的*),您无需将它们转换为_bstr_t。

注:转换后的字符串的寿命是CW2A对象的生命周期,所以你需要把它转换成字符串类,如:

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