Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
De ATL-klasse CComBSTR biedt een wrapper rond het BSTR-gegevenstype. Hoewel CComBSTR dit een nuttig hulpmiddel is, zijn er verschillende situaties waarin voorzichtigheid is vereist.
Problemen met conversie
Hoewel verschillende CComBSTR methoden automatisch een ANSI-tekenreeksargument converteren naar Unicode, retourneren de methoden altijd Unicode-indelingstekenreeksen. Als u de uitvoertekenreeks wilt converteren naar ANSI, gebruikt u een ATL-conversieklasse. Zie ATL- en MFC-tekenreeksconversiemacro's voor meer informatie over de ATL-conversieklassen.
Voorbeeld
// 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);
Als u een letterlijke tekenreeks gebruikt om een CComBSTR object te wijzigen, gebruikt u brede tekenreeksen om onnodige conversies te verminderen.
// The following converts the ANSI string to Unicode
CComBSTR bstr1("Test");
// The following uses a Unicode string at compile time
CComBSTR bstr2(L"Test");
Bereikproblemen
Net als bij elke goed opgevoede klasse, CComBSTR wordt de resources vrijgemaakt wanneer het uit zijn bereik komt. Als een functie een aanwijzer naar de CComBSTR tekenreeks retourneert, kan dit problemen veroorzaken, omdat de aanwijzer verwijst naar geheugen dat al is vrijgemaakt. In deze gevallen gebruikt u de Copy methode, zoals hieronder wordt weergegeven.
Voorbeeld
// 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);
}
Het CComBSTR-object expliciet vrijmaken
Het is mogelijk om de tekenreeks die in het CComBSTR object is opgenomen, expliciet vrij te maken voordat het object buiten bereik raakt. Als de string wordt vrijgegeven, is het CComBSTR object ongeldig.
Voorbeeld
// 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.
CComBSTR-objecten in lussen gebruiken
Aangezien de CComBSTR klasse een buffer toewijst om bepaalde bewerkingen uit te voeren, zoals de += operator of Append methode, wordt het afgeraden om tekenreeksbewerkingen uit te voeren binnen een strakke lus. In deze situaties CStringT biedt u betere prestaties.
Voorbeeld
// This is not an efficient way to use a CComBSTR object.
CComBSTR bstrMyString;
HRESULT hr;
while (bstrMyString.Length() < 1000)
hr = bstrMyString.Append(L"*");
Problemen met geheugenlekken
Het doorgeven van het adres van een geïnitialiseerd CComBSTR aan een functie als een [out] -parameter veroorzaakt een geheugenlek.
In het onderstaande voorbeeld wordt de tekenreeks die is toegewezen om de tekenreeks "Initialized" vast te houden gelekt wanneer de functie MyGoodFunction de tekenreeks vervangt.
CComBSTR bstrLeak(L"Initialized");
HRESULT hr = MyGoodFunction(&bstrLeak);
Als u het lek wilt voorkomen, roept u de Empty methode aan voor bestaande CComBSTR objecten voordat u het adres doorgeeft als een [out] -parameter.
Houd er rekening mee dat dezelfde code geen lek zou veroorzaken als de parameter van de functie [in, uit] was.
Zie ook
Concepten
CStringT-klasse
wstring
Macro's voor tekenreeksconversie