Compartir a través de


Programar con CComBSTR (ATL)

La clase de ATL CComBSTR proporciona un contenedor alrededor del tipo de datos BSTR. Aunque CComBSTR es una herramienta muy útil, hay varias situaciones que requieren precaución.

Problemas de conversión

Aunque varios métodos de CComBSTR convertirán automáticamente un argumento de cadena ANSI en Unicode, los métodos siempre devolverán cadenas en formato Unicode. Para volver a convertir la cadena de salida en ANSI, use una clase de conversión ATL. Para más información sobre las clases de conversión ATL, consulte Macros de conversión de cadenas ATL y MFC.

Ejemplo

// 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 usa un literal de cadena para modificar un objeto CComBSTR, use cadenas de caracteres anchos para reducir las conversiones innecesarias.

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

Problemas de ámbito

Igual que sucede con cualquier otra clase que funcione como se espera de ella, CComBSTR liberará sus recursos cuando salga del ámbito. Si una función devuelve un puntero a la cadena CComBSTR, pueden aparecer problemas, ya que el puntero hará referencia a la memoria que se ha liberado. En estos casos, use el método Copy, como se muestra a continuación.

Ejemplo

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

Liberación explícita del objeto CComBSTR

La cadena que contiene el objeto CComBSTR se puede liberar explícitamente antes de que el objeto salga del ámbito. Si se libera la cadena, el objeto CComBSTR no es válido.

Ejemplo

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

Uso de objetos CComBSTR en bucles

Como la clase CComBSTR asigna un búfer para realizar determinadas operaciones, como el operador += o el Append método, no se recomienda realizar la manipulación de cadenas dentro de un bucle ajustado. En estas situaciones, CStringT proporciona un mejor rendimiento.

Ejemplo

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

Problemas de fuga de memoria

Si se pasa la dirección de un CComBSTR inicializado a una función como un parámetro [out], se produce una fuga de memoria.

En el ejemplo siguiente, la cadena asignada para contener la cadena "Initialized" tiene una fuga cuando la función MyGoodFunction reemplaza la cadena.

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

Para evitar la fuga, llame al método Empty en los objetos CComBSTR existentes antes de pasar la dirección como un parámetro [out].

Tenga en cuenta que el mismo código no provocaría una fuga si el parámetro de la función fuera [in, out].

Consulte también

Conceptos
CStringT (clase)
wstring
Macros de conversión de cadena