Condividi tramite


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