Programmazione con CComBSTR (ATL)
La classe ATL CComBSTR fornisce un wrapper intorno al tipo di dati BSTR. Sebbene CComBSTR
sia uno strumento utile, esistono diverse situazioni che richiedono cautela.
Problemi di conversione
Anche se diversi CComBSTR
metodi convertiranno automaticamente un argomento stringa ANSI in Unicode, i metodi restituiranno sempre stringhe di formato Unicode. Per convertire nuovamente la stringa di output in ANSI, usare una classe di conversione ATL. Per altre informazioni sulle classi di conversione ATL, vedere Macro di conversione di stringhe ATL e MFC.
Esempio
// 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 si usa un valore letterale stringa per modificare un CComBSTR
oggetto, usare stringhe di caratteri wide per ridurre le conversioni non necessarie.
// The following converts the ANSI string to Unicode
CComBSTR bstr1("Test");
// The following uses a Unicode string at compile time
CComBSTR bstr2(L"Test");
Problemi di ambito
Come per qualsiasi classe ben comportata, CComBSTR
libera le risorse quando esce dall'ambito. Se una funzione restituisce un puntatore alla stringa, questo può causare problemi, perché il puntatore farà riferimento alla CComBSTR
memoria che è già stata liberata. In questi casi, usare il Copy
metodo , come illustrato di seguito.
Esempio
// 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);
}
Liberare in modo esplicito l'oggetto CComBSTR
È possibile liberare in modo esplicito la stringa contenuta nell'oggetto prima che l'oggetto esce dall'ambito CComBSTR
. Se la stringa viene liberata, l'oggetto CComBSTR
non è valido.
Esempio
// 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.
Uso di oggetti CComBSTR nei cicli
Poiché la CComBSTR
classe alloca un buffer per eseguire determinate operazioni, ad esempio l'operatore o Append
il +=
metodo, non è consigliabile eseguire la manipolazione delle stringhe all'interno di un ciclo stretto. In queste situazioni, CStringT
offre prestazioni migliori.
Esempio
// This is not an efficient way to use a CComBSTR object.
CComBSTR bstrMyString;
HRESULT hr;
while (bstrMyString.Length() < 1000)
hr = bstrMyString.Append(L"*");
Problemi di perdita di memoria
Il passaggio dell'indirizzo di un oggetto inizializzato CComBSTR
a una funzione come parametro [out] causa una perdita di memoria.
Nell'esempio seguente la stringa allocata per contenere la stringa "Initialized"
viene persa quando la funzione MyGoodFunction
sostituisce la stringa.
CComBSTR bstrLeak(L"Initialized");
HRESULT hr = MyGoodFunction(&bstrLeak);
Per evitare la perdita, chiamare il Empty
metodo sugli oggetti esistenti CComBSTR
prima di passare l'indirizzo come parametro [out].
Si noti che lo stesso codice non provocherebbe una perdita se il parametro della funzione era [in, out].
Vedi anche
Concetti
Classe CStringT
wstring
Macro di conversione di stringhe