2010-06-22 11 views
4

je le code qui utilise la macro USE_CONVERSION dans un projet C++ ...Faire sans USES_CONVERSION macro

Je me demandais si cela est bien écrit, (pas écrit par moi), et s'il y a de meilleures façons de faites-le, sans les macros USES_CONVERSION et 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

Comme il y a aussi un BSTR, il ressemble à des choses MFC/ATL de Microsoft. Veuillez marquer en conséquence. – MSalters

+0

BSTR est un type Win32 (Platform SDK). _bstr_t fait également partie du Platform SDK (il est utilisé par #import). – reece

Répondre

5

Il est basé sur la classe ATL :: CA2W et les amis (en Atlconv.h, je crois) qui ne met pas la chaîne sur la pile et ne pas utiliser des macros. Vous n'avez pas besoin USES_CONVERSION dans la fonction:

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

En outre, étant donné que vos arguments sont BSTR (wchar_t *), vous n'avez pas besoin de les convertir en _bstr_t.

NOTE: La durée de vie de la chaîne convertie est la durée de vie de l'objet CW2A, vous aurez donc besoin de le mettre dans une classe de chaîne, par exemple:

CStringA arg = CW2A(bstrArg);

NOTE 2: pbstrValue est une sortie valeur. L'instance _bstr_t détruira la mémoire allouée pour le BSTR. Par conséquent, vous devez soit utiliser SysAllocString directement ou détacher le BSTR:

pbstrValue = SysAllocString(CA2W(retval));

ou:

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

NOTE 3: Utilisation explicite des opérateurs de conversion (.operator BSTR()) n'est pas nécessaire - Le compilateur appellera le bon pour vous.

REMARQUE 4: Comme cela ressemble à un appel COM, vous ne voulez vraiment pas déclencher une exception C++. Vous voulez probablement définir un objet IErrorInfo (probablement avec un assistant):

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