Partager via


Programmation avec CComBSTR (ATL)

La classe ATL CComBSTR fournit un wrapper autour du type de données BSTR. Bien qu’il CComBSTR s’agit d’un outil utile, il existe plusieurs situations qui nécessitent une prudence.

Problèmes de conversion

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

Exemple

// 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 CComBSTR objet, utilisez des chaînes de caractères larges pour réduire les conversions inutiles.

// 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 d’étendue

Comme avec n’importe quelle classe bien comportée, CComBSTR libère ses ressources lorsqu’elle sort de l’étendue. Si une fonction retourne un pointeur vers la CComBSTR chaîne, cela peut entraîner 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 Copy méthode, comme indiqué ci-dessous.

Exemple

// 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ération explicite de l’objet CComBSTR

Il est possible de libérer explicitement la chaîne contenue dans l’objet CComBSTR avant la sortie de l’objet. Si la chaîne est libérée, l’objet CComBSTR n’est pas valide.

Exemple

// 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.   

Utilisation d’objets CComBSTR dans des boucles

Comme la CComBSTR classe alloue une mémoire tampon pour effectuer certaines opérations, telles que l’opérateur ou Append la += méthode, il n’est pas recommandé d’effectuer une manipulation de chaîne à l’intérieur d’une boucle serrée. Dans ces situations, CStringT vous obtenez de meilleures performances.

Exemple

// 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

Le passage de l’adresse d’une fonction initialisée CComBSTR en tant que paramètre [out] provoque une fuite de mémoire.

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

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

Pour éviter la fuite, appelez la Empty méthode sur les objets existants CComBSTR avant de passer l’adresse en tant que paramètre [out].

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

Voir aussi

Concepts
CStringT, classe
wstring
Macros de conversion de chaînes