Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Uwaga / Notatka
Aktywna biblioteka szablonów (ATL) nadal jest obsługiwana. Nie dodajemy już funkcji ani nie aktualizujemy dokumentacji.
Klasa ATL CComBSTR zapewnia opakowanie dla typu danych BSTR. Chociaż CComBSTR jest to przydatne narzędzie, istnieje kilka sytuacji, które wymagają ostrożności.
Problemy z konwersją
Chociaż kilka CComBSTR metod automatycznie konwertuje argument ciągu ANSI na Unicode, metody zawsze zwracają ciągi formatu Unicode. Aby przekonwertować ciąg wyjściowy z powrotem na ANSI, użyj klasy konwersji ATL. Aby uzyskać więcej informacji na temat klas konwersji ATL, zobacz Makra konwersji ciągów ATL i MFC.
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 literału ciągu do modyfikowania CComBSTR obiektu, użyj ciągów znaków szerokich, aby zmniejszyć niepotrzebne konwersje.
// The following converts the ANSI string to Unicode
CComBSTR bstr1("Test");
// The following uses a Unicode string at compile time
CComBSTR bstr2(L"Test");
Problemy z zakresem
Podobnie jak w przypadku każdej dobrze zachowującej się klasy, CComBSTR zwalnia zasoby, gdy wychodzi poza swój zakres działania. Jeśli funkcja zwróci wskaźnik do CComBSTR łańcucha znaków, może to spowodować problemy, ponieważ wskaźnik odwołuje się do pamięci, która została już zwolniona. W takich przypadkach użyj metody Copy, 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);
}
Jawne zwalnianie obiektu CComBSTR
Istnieje możliwość jawnego zwolnienia ciągu zawartego w obiekcie CComBSTR przed zakończeniem jego zakresu. Jeśli ciąg zostanie zwolniony, CComBSTR obiekt staje się 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.
Używanie obiektów CComBSTR w pętlach
CComBSTR Ponieważ klasa przydziela bufor do wykonywania niektórych operacji, takich jak += operator lub Append metoda, nie zaleca się wykonywania manipulowania ciągami wewnątrz ciasnej pętli. 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 z przeciekiem pamięci
Przekazanie adresu zainicjowanego CComBSTR do funkcji jako parametr [wyjściowy] powoduje wyciek pamięci.
W poniższym przykładzie ciąg przydzielony do przechowywania ciągu "Initialized" jest wyciekany, gdy funkcja MyGoodFunction zastępuje ciąg.
CComBSTR bstrLeak(L"Initialized");
HRESULT hr = MyGoodFunction(&bstrLeak);
Aby uniknąć wycieku, wywołaj Empty metodę dla istniejących CComBSTR obiektów przed przekazaniem adresu jako [out] parametru.
Należy pamiętać, że ten sam kod nie spowoduje wycieku, jeśli parametr funkcji był [w, out].
Zobacz też
Pojęcia
Klasa CStringT
wstring
Makra konwersji ciągów znaków