利用 CComBSTR
ATL 類別 CComBSTR 在 BSTR 資料型別周圍的包裝函式。 當 CComBSTR 非常實用的工具時,不需要注意的數種情況。
轉換問題。
範圍問題
明確釋放 CComBSTR 物件
在迴圈中使用 CComBSTR 物件
記憶體遺漏問題
轉換問題。
雖然許多 CComBSTR 方法會自動轉換成 ANSI 字串引數到 Unicode,方法永遠都會傳回 Unicode 格式字串。 若要轉換輸出至 ANSI 字串,請使用 ATL 轉換類別。 如需轉換 ATL 類別的詳細資訊,請參閱 ATL 和 MFC 字串轉換巨集。
範例
// 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);
如果您使用字串常值 (String Literal) CComBSTR 修改物件,請使用寬字元字串。 這會減少不必要的轉換。
範例
// The following converts the ANSI string to Unicode
CComBSTR bstr1("Test");
// The following uses a Unicode string at compile time
CComBSTR bstr2(L"Test");
範圍問題
會在超出範圍,以及任何行為良好的類別, CComBSTR 會釋放其資源。 如果函式傳回指向 CComBSTR 字串,這可能會造成問題,因為,指標會參考已經釋放的記憶體。 在這些情況下,請使用 複本 方法,如下所示。
範例
// 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);
}
明確釋放 CComBSTR 物件
在物件超出範圍之前,它可以是明確的可用 CComBSTR 物件包含的字串。 如果資料已釋放, CComBSTR 物件無效。
範例
// 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 物件
因為 CComBSTR 類別配置緩衝區執行某些作業,例如 += 運算子或 附加 方法,建議您不要執行在緊密迴圈內的字串管理。 在這些情況下, CStringT 提供更好的效能。
範例
// This is not an efficient way to use a CComBSTR object.
CComBSTR bstrMyString;
HRESULT hr;
while (bstrMyString.Length() < 1000)
hr = bstrMyString.Append(L"*");
記憶體遺漏問題
傳遞初始化的 CComBSTR 的位址會當做參數 [out] 造成記憶體遺漏 (Memory Leak)。
在下列範例中,當函式 MyGoodFunction 取代字串時,配置的字串,會保留字串 "Initialized" 遺漏。
CComBSTR bstrLeak(L"Initialized");
HRESULT hr = MyGoodFunction(&bstrLeak);
若要避免遺漏,請在傳遞這個位址之前呼叫在現有的 CComBSTR 物件的 空 方法做為 [out] 參數。
請注意相同的程式碼不會造成遺漏,如果函式的參數是 [in, out]。