Programmieren mit CComBSTR (ATL)

Die ATL-Klasse CComBSTR stellt einen Wrapper um den BSTR-Datentyp bereit. Obwohl CComBSTR es sich um ein nützliches Tool handelt, gibt es mehrere Situationen, die Vorsicht erfordern.

Konvertierungsprobleme

Obwohl mehrere CComBSTR Methoden automatisch ein ANSI-Zeichenfolgenargument in Unicode konvertieren, geben die Methoden immer Unicode-Formatzeichenfolgen zurück. Verwenden Sie eine ATL-Konvertierungsklasse, um die Ausgabezeichenfolge wieder in ANSI zu konvertieren. Weitere Informationen zu den ATL-Konvertierungsklassen finden Sie unter ATL- und MFC-Zeichenfolgenkonvertierungsmakros.

Beispiel

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

Wenn Sie ein Zeichenfolgenliteral zum Ändern eines CComBSTR Objekts verwenden, verwenden Sie breite Zeichenfolgen, um unnötige Konvertierungen zu reduzieren.

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

Bereichsprobleme

Wie bei jeder gut verhaltenen Klasse werden die Ressourcen freigegeben, CComBSTR wenn sie nicht mehr in den Gültigkeitsbereich gelangen. Wenn eine Funktion einen Zeiger auf die CComBSTR Zeichenfolge zurückgibt, kann dies Zu Problemen führen, da der Zeiger auf den Speicher verweist, der bereits freigegeben wurde. Verwenden Sie in diesen Fällen die Copy Methode, wie unten dargestellt.

Beispiel

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

Explizites Freigeben des CComBSTR-Objekts

Es ist möglich, die im CComBSTR Objekt enthaltene Zeichenfolge explizit frei zu geben, bevor das Objekt den Bereich ausgibt. Wenn die Zeichenfolge freigegeben wird, ist das CComBSTR Objekt ungültig.

Beispiel

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

Verwenden von CComBSTR-Objekten in Schleifen

Da die CComBSTR Klasse einen Puffer zuweist, um bestimmte Vorgänge auszuführen, z. B. den Operator oder Append die += Methode, empfiehlt es sich nicht, Zeichenfolgenmanipulation in einer engen Schleife durchzuführen. In diesen Situationen CStringT bietet eine bessere Leistung.

Beispiel

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

Speicherleckprobleme

Das Übergeben der Adresse einer initialisierten CComBSTR Funktion als [out] -Parameter führt zu einem Speicherverlust.

Im folgenden Beispiel wird die Zeichenfolge, die der Zeichenfolge "Initialized" zugeordnet ist, geleckt, wenn die Funktion MyGoodFunction die Zeichenfolge ersetzt.

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

Um das Leck zu vermeiden, rufen Sie die Empty Methode für vorhandene CComBSTR Objekte auf, bevor Sie die Adresse als [out] -Parameter übergeben.

Beachten Sie, dass derselbe Code keinen Verlust verursachen würde, wenn der Parameter der Funktion [in, out] war.

Siehe auch

Konzepte
CStringT-Klasse
wstring
Zeichenfolgenkonvertierungs-Makros