Programmierung mit CComBSTR

Die ATL-Klasse CComBSTR stellt einen Wrapper um den BSTR Datentyp bereit.Während CComBSTR ein nützliches Tool ist, gibt es einige Situationen, die Vorsicht erfordern.

  • Konvertierungsprobleme

  • Bereichs-Probleme

  • Das CComBSTR-Objekt explizit freigeben

  • Verwenden CComBSTR-Objekte in-Schleifen

  • Speicherverlust-Probleme

Konvertierungsprobleme

Obwohl einige CComBSTR-Methoden automatisch ein ANSI-Zeichenfolgenargument in Unicode konvertieren, geben die Methoden immer Unicode-Formatzeichenfolgen zurück.Um die Ausgabezeichenfolge zurück in ANSI zu konvertieren, verwenden Sie eine ATL-Konvertierungsklasse.Weitere Informationen über die ATL-Konvertierungsklassen, finden Sie unter ATL und Makros für MFC-Zeichenfolgenkonvertierung.

bdyd6xz6.collapse_all(de-de,VS.110).gifBeispiel

// 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 verwenden, um ein CComBSTR-Objekt zu ändern, verwenden Sie Breitzeichen-Zeichenfolgen.Dies reduziert unnötige Konvertierungen.

bdyd6xz6.collapse_all(de-de,VS.110).gifBeispiel

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

Bereichs-Probleme

Wie bei allen gut konzipierte Klasse, gibt CComBSTR seine Ressourcen frei, wenn sie den Gültigkeitsbereich verlässt.Wenn eine Funktion einen Zeiger auf die CComBSTR Zeichenfolge zurückgibt, kann diese Probleme verursachen, da der Zeiger Arbeitsspeicher verweist, der bereits freigegeben ist.In diesen Fällen verwenden Sie die Methode Copy, wie unten dargestellt.

bdyd6xz6.collapse_all(de-de,VS.110).gifBeispiel

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

Das CComBSTR-Objekt explizit freigeben

Es ist möglich, die Zeichenfolge explizit freizugeben, die im CComBSTR-Objekt enthalten ist, bevor das Objekt Gültigkeitsbereich verlässt.Wenn die Zeichenfolge verworfen wird, ist das Objekt CComBSTR ungültig.

bdyd6xz6.collapse_all(de-de,VS.110).gifBeispiel

// 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 CComBSTR-Objekte in-Schleifen

Da die CComBSTR-Klasse einen Puffer erfolgt, um bestimmte Vorgänge, wie der +=-Operator oder die Append-Methode auszuführen, wird es nicht empfohlen, Zeichenfolgenbearbeitung innerhalb einer kurzen Schleife ausführen.In diesen Situationen stellt CStringT eine bessere Leistung.

bdyd6xz6.collapse_all(de-de,VS.110).gifBeispiel

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

Speicherverlust-Probleme

Die Übergabe der Adresse von initialisierten CComBSTR zu einer Funktion als [out]-Parameter verursacht einen Speicherverlust.

Im Beispiel unten, wird die Zeichenfolge, die zugeordnet ist, um die Zeichenfolge "Initialized" anzuhalten, verloren geht, wenn die Funktion MyGoodFunction die Zeichenfolge ersetzt.

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

Um den Verlust zu vermeiden, rufen Sie die Methode Empty auf vorhandene CComBSTR-Objekten auf bevor Sie die Adresse als [out]-Parameter übergeben.

Beachten Sie, dass der gleiche Code ohne Datenverlust führen würde, wenn der Parameter der Funktion [in, out] war.

Siehe auch

Referenz

CStringT-Klasse

wstring

Weitere Ressourcen

ATL-Konzepte

Makros für Zeichenfolgenkonvertierung