Partilhar via


Programação com CComBSTR (ATL)

A classe ATL CComBSTR fornece um wrapper em torno do tipo de dados BSTR. Embora CComBSTR seja uma ferramenta útil, existem várias situações que exigem cautela.

Problemas de conversão

Embora vários CComBSTR métodos convertam automaticamente um argumento de cadeia de caracteres ANSI em Unicode, os métodos sempre retornarão cadeias de caracteres de formato Unicode. Para converter a cadeia de caracteres de saída de volta para ANSI, use uma classe de conversão ATL. Para obter mais informações sobre as classes de conversão ATL, consulte Macros de conversão de cadeia de caracteres ATL e MFC.

Exemplo

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

Se você estiver usando um literal de cadeia de caracteres para modificar um CComBSTR objeto, use cadeias de caracteres largas para reduzir conversões desnecessárias.

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

Questões de escopo

Como acontece com qualquer classe bem comportada, CComBSTR vai liberar seus recursos quando sair do escopo. Se uma função retornar um ponteiro para a CComBSTR cadeia de caracteres, isso pode causar problemas, pois o ponteiro fará referência à memória que já foi liberada. Nestes casos, use o Copy método, como mostrado abaixo.

Exemplo

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

Liberando explicitamente o objeto CComBSTR

É possível liberar explicitamente a cadeia de caracteres contida no objeto antes que o objeto saia do CComBSTR escopo. Se a cadeia de caracteres for liberada, o CComBSTR objeto será inválido.

Exemplo

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

Usando objetos CComBSTR em loops

Como a CComBSTR classe aloca um buffer para executar determinadas operações, como o += operador ou o Append método, não se recomenda realizar a manipulação de strings dentro de um ciclo apertado. Nestas situações, CStringT proporciona um melhor desempenho.

Exemplo

// 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 memória

Passar o endereço de um objeto CComBSTR inicializado para uma função como um parâmetro de saída [out] causa um vazamento de memória.

No exemplo abaixo, a string alocada para manter a string "Initialized" é vazada quando a função MyGoodFunction substitui a string.

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

Para evitar o vazamento, chame o método Empty em objetos CComBSTR existentes antes de passar o endereço como parâmetro [out] .

Observe que o mesmo código não causaria um vazamento se o parâmetro da função fosse [in, out].

Ver também

Conceitos
Classe CStringT
corda de corda
Macros de conversão de strings