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