Programação com CComBSTR
A classe CComBSTR de ATL fornece um wrapper em torno do tipo de dados de BSTR .Quando CComBSTR é uma ferramenta útil, há várias situações que exigem cuidados.
Problemas de conversão
Problemas de escopo
Liberando explicitamente o objeto de CComBSTR
Usando objetos de CComBSTR em loop
Problemas de vazamento de memória
Problemas de conversão
Embora vários métodos de CComBSTR convertam automaticamente um argumento de cadeia de caracteres ANSI em Unicode, os métodos retornará sempre cadeias de caracteres de formato Unicode.Para converter uma cadeia de caracteres de saída de volta para ANSI, use uma classe de conversão de ATL.Para obter mais informações sobre as classes de conversão de ATL, consulte Macros de conversão de cadeia de caracteres de ATL e de 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 uma cadeia de caracteres literal para modificar um objeto de CComBSTR , use cadeias de caracteres com.Isso reduzirá conversões desnecessárias.
Exemplo
// 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 escopo
Como com qualquer uma classe, CComBSTR irá liberar os recursos quando sai do escopo.Se uma função retorna um ponteiro para a cadeia de caracteres de CComBSTR , isso pode causar problemas, porque o ponteiro fará referência a memória que já tenha sido liberado.Em esses casos, use o método de Copiar , 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 de CComBSTR
É possível definir explicitamente a cadeia de caracteres contido no objeto de CComBSTR antes de sair do objeto escopo.Se a cadeia de caracteres é laçada, o objeto de CComBSTR é 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 de CComBSTR em loop
Porque a classe de CComBSTR atribui um buffer para executar certas operações, como o operador de += ou o método de Acrescentar , não é recomendável que você execute a manipulação de cadeia de caracteres dentro de um loop. forteEm essas situações, CStringT fornece 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 vazamento de memória
Passar o endereço de CComBSTR inicializado para uma função como um parâmetro de [out] causa um vazamento de memória.
Em o exemplo abaixo, a cadeia de caracteres atribuída para armazenar a cadeia de caracteres "Initialized" é vazada quando a função MyGoodFunction substitui a cadeia de caracteres.
CComBSTR bstrLeak(L"Initialized");
HRESULT hr = MyGoodFunction(&bstrLeak);
Para evitar o escape, chame o método de Vazio em objetos existentes de CComBSTR antes de passar o endereço como um parâmetro de [out] .
Observe que o mesmo código não poderiam causar um escape se o parâmetro de função foi [in, out].