Sdílet prostřednictvím


Programování pomocí třídy CComBSTR (ATL)

TŘÍDA ATL CComBSTR poskytuje obálku kolem datového typu BSTR. I když CComBSTR je užitečný nástroj, existuje několik situací, které vyžadují opatrnost.

Problémy s převodem

I když několik CComBSTR metod automaticky převede argument řetězce ANSI na Unicode, metody vždy vrátí řetězce formátu Unicode. Chcete-li převést výstupní řetězec zpět na ANSI, použijte třídu převodu ATL. Další informace o třídách převodu KNIHOVNY ATL naleznete v tématu ATL a MFC String Conversion Macros.

Příklad

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

Pokud k úpravě objektu CComBSTR používáte řetězcový literál, snižte nepotřebné převody pomocí širokých znakových řetězců.

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

Problémy s oborem

Stejně jako u jakékoli dobře se chovné třídy uvolní své prostředky, CComBSTR jakmile vyjde mimo rozsah. Pokud funkce vrátí ukazatel na CComBSTR řetězec, může to způsobit problémy, protože ukazatel bude odkazovat na paměť, která již byla uvolněna. V těchto případech použijte metodu Copy , jak je znázorněno níže.

Příklad

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

Explicitní uvolnění objektu CComBSTR

Je možné explicitně uvolnit řetězec obsažený v objektu CComBSTR předtím, než objekt přejde do oboru. Pokud je řetězec uvolněn, CComBSTR objekt je neplatný.

Příklad

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

Použití objektů CComBSTR ve smyčce

Vzhledem k tomu CComBSTR , že třída přiděluje vyrovnávací paměť k provádění určitých operací, jako += je operátor nebo Append metoda, nedoporučujeme provádět manipulaci s řetězci uvnitř těsné smyčky. V těchto situacích CStringT poskytuje lepší výkon.

Příklad

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

Problémy s nevrácenou pamětí

Předání adresy inicializované CComBSTR funkce jako parametru [out] způsobí nevracení paměti.

V následujícím příkladu je řetězec přidělený k uložení řetězce "Initialized" nevracený, když funkce MyGoodFunction nahradí řetězec.

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

Chcete-li zabránit úniku, zavolejte metodu Empty u existujících CComBSTR objektů před předáním adresy jako parametru [out].

Všimněte si, že stejný kód by nezpůsobil únik, pokud by parametr funkce byl [in, out].

Viz také

Koncepty
CStringT – třída
wstring
Makra převodu řetězců