2010-06-22 60 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; }