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