Programowanie z CComBSTR
Klasy ATL CComBSTR udostępnia otokę BSTR typu danych.Podczas gdy CComBSTR jest użytecznym narzędziem, istnieje kilka sytuacji, które wymagają ostrożność.
Problemy przy konwersji
Zakres problemów
Zwalnianie jawnie obiektu CComBSTR
Przy użyciu obiektów CComBSTR w pętli
Problemy przeciek pamięci
Problemy przy konwersji
Chociaż wiele CComBSTR metody automatycznie przekonwertować argumentu ciąg ANSI na Unicode, metod zawsze zwraca ciągi formatu Unicode.Aby przekonwertować ciąg wyjściowy ANSI, należy użyć klasy ATL konwersji.Więcej informacji dotyczących klasy ATL konwersji, zobacz ATL i MFC ciąg Konwersja makra.
Przykład
// 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);
Jeśli używasz zmodyfikować literału ciągu CComBSTR obiektów, użyj ciągów znaków szerokości.Zmniejszy to konwersje niepotrzebne.
Przykład
// The following converts the ANSI string to Unicode
CComBSTR bstr1("Test");
// The following uses a Unicode string at compile time
CComBSTR bstr2(L"Test");
Zakres problemów
Podobnie jak w przypadku dowolnej klasy dobrze działające CComBSTR wolny z jego zasobów, gdy wykracza on poza zakres.Jeśli funkcja zwraca wskaźnik do CComBSTR ciąg, może to powodować problemy, jak wskaźnik będzie odwoływać się do pamięci, która już została zwolniona.W tych przypadkach należy użyć kopię metody, jak pokazano poniżej.
Przykład
// 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);
}
Zwalnianie jawnie obiektu CComBSTR
Jest możliwe jawnie wolne ciąg znajdujący się w CComBSTR obiektu obiekt przejdzie się zakres.Jeśli ciąg jest zwalniany, CComBSTR obiektu jest nieprawidłowy.
Przykład
// 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.
Przy użyciu obiektów CComBSTR w pętli
Jako CComBSTR klasy alokuje bufor do wykonywania niektórych operacji, takich jak += operatora lub Append metodę, nie jest zalecane wykonanie manipulowanie ciągami wewnątrz pętli ścisła.W takich sytuacjach CStringT zapewnia lepszą wydajność.
Przykład
// This is not an efficient way to use a CComBSTR object.
CComBSTR bstrMyString;
HRESULT hr;
while (bstrMyString.Length() < 1000)
hr = bstrMyString.Append(L"*");
Problemy przeciek pamięci
Przekazując adres zainicjowany CComBSTR do funkcji jako [out] parametr powoduje przeciek pamięci.
W poniższym przykładzie ciąg jest przeznaczona do przechowywania ciągu "Initialized" jest przecieku, kiedy funkcja MyGoodFunction zamienia ciąg.
CComBSTR bstrLeak(L"Initialized");
HRESULT hr = MyGoodFunction(&bstrLeak);
Aby uniknąć wycieku, wywołanie pusty metody na istniejącym CComBSTR obiektów przed przekazaniem adresów jako [out] parametru.
Należy zauważyć, że ten sam kod nie spowodowałoby przeciek, jeśli został parametr funkcji [out,].