Partager via


Programmation avec CComBSTR

La classe CComBSTR ATL fournit un wrapper autour de le type de données d' BSTR .Pendant qu' CComBSTR est un outil utile, il existe plusieurs situations qui requièrent l'avertissement.

  • Problèmes de conversion

  • Problèmes de portée

  • Libérer explicitement l'objet de CComBSTR

  • À l'aide de objets de CComBSTR dans les boucles

  • Problèmes de fuite de mémoire

Problèmes de conversion

Bien que plusieurs méthodes d' CComBSTR convertissent automatiquement un argument de chaîne ANSI dans Unicode, les méthodes retournent toujours les chaînes au format Unicode.Pour convertir la chaîne de sortie vers ANSI, utilisez une classe de conversion ATL.Pour plus d'informations sur les classes de conversion ATL, consultez Macros de conversion de chaînes ATL et MFC.

bdyd6xz6.collapse_all(fr-fr,VS.110).gifExemple

// Declare a CComBSTR object. Although the argument is ANSI,
// the constructor converts it into UNICODE.
CComBSTR bstrMyString("Hello World");
// Convert the string into an ANSI string
CW2A szMyString(bstrMyString);
// Display the ANSI string
MessageBoxA(NULL, szMyString, "String Test", MB_OK);   

Si vous utilisez un littéral de chaîne pour modifier un objet d' CComBSTR , utilisez des chaînes à caractères larges.Cela réduira des conversions inutiles.

bdyd6xz6.collapse_all(fr-fr,VS.110).gifExemple

// The following converts the ANSI string to Unicode
CComBSTR bstr1("Test");
// The following uses a Unicode string at compile time 
CComBSTR bstr2(L"Test");   

Problèmes de portée

Comme avec n'importe quelle classe polie, CComBSTR libère les ressources lorsqu'il est hors de portée.Si une fonction retourne un pointeur vers la chaîne d' CComBSTR , cela peut provoquer des problèmes, car le pointeur référence la mémoire qui a déjà été libérée.Dans ces cas, utilisez la méthode de Copier , comme indiqué ci-dessous.

bdyd6xz6.collapse_all(fr-fr,VS.110).gifExemple

// The wrong way to do it
BSTR * MyBadFunction()
{
   // Create the CComBSTR object
   CComBSTR bstrString(L"Hello World");
   // Convert the string to uppercase
   HRESULT hr;
   hr = bstrString.ToUpper();

   // Return a pointer to the BSTR. ** Bad thing to do **
   return &bstrString;
}
// The correct way to do it
HRESULT MyGoodFunction(/*[out]*/ BSTR* bstrStringPtr)
{
   // Create the CComBSTR object
   CComBSTR bstrString(L"Hello World");
   // Convert the string to uppercase
   HRESULT hr;
   hr = bstrString.ToUpper();
   if (hr != S_OK)
       return hr;
   // Return a copy of the string.
   return bstrString.CopyTo(bstrStringPtr);
}

Libérer explicitement l'objet de CComBSTR

Il est possible de libérer explicitement la chaîne contenue dans l'objet d' CComBSTR avant que l'objet afin portée.Si la chaîne est libérée, l'objet d' CComBSTR est incorrect.

bdyd6xz6.collapse_all(fr-fr,VS.110).gifExemple

// Declare a CComBSTR object
CComBSTR bstrMyString(L"Hello World");
// Free the string explicitly
::SysFreeString(bstrMyString);
// The string will be freed a second time
// when the CComBSTR object goes out of scope,
// which is invalid.   

À l'aide de objets de CComBSTR dans les boucles

Comme la classe d' CComBSTR alloue une mémoire tampon afin d'exécuter certaines opérations, telles que l'opérateur d' += ou la méthode de Ajouter , il n'est pas recommandé d'exécuter la manipulation de chaînes dans une boucle serrée.Dans ces situations, CStringT offre de meilleures performances.

bdyd6xz6.collapse_all(fr-fr,VS.110).gifExemple

// This is not an efficient way to use a CComBSTR object.
CComBSTR bstrMyString;
HRESULT hr;
while (bstrMyString.Length() < 1000)
   hr = bstrMyString.Append(L"*");   

Problèmes de fuite de mémoire

Obtenir l'adresse d' CComBSTR initialisé à une fonction comme paramètre de [out] provoque une fuite de mémoire.

Dans l'exemple ci-dessous, la chaîne allouée pour contenir la chaîne "Initialized" est coulée lorsque la fonction MyGoodFunction remplace la chaîne.

CComBSTR bstrLeak(L"Initialized");
HRESULT hr = MyGoodFunction(&bstrLeak);   

Pour éviter une fuite, appelez la méthode de Vide exister sur des objets d' CComBSTR avant de passer l'adresse comme paramètre de [out] .

Notez que le même code ne provoquerait pas une fuite si le paramètre de la fonction était [in, out].

Voir aussi

Référence

Classe de CStringT

wstring

Autres ressources

Concepts ATL

Macros de conversion de chaînes