使用 CComBSTR 進行程式設計 (ATL)
ATL 類別 CComBSTR 提供 BSTR 資料類型的包裝函式。 雖然 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);
如果您使用字串常值來修改 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
指標,這可能會造成問題,因為指標會參考已釋放的記憶體。 在這些情況下,請使用 Copy
方法,如下所示。
範例
// 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
會配置緩衝區來執行某些作業,例如 +=
運算子或 Append
方法,因此不建議您在緊密迴圈內執行字串操作。 在這些情況下, 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] 參數,會導致記憶體流失。
在下列範例中,配置來保存字串的字串會在函式取代字串 "Initialized"
時 MyGoodFunction
外泄。
CComBSTR bstrLeak(L"Initialized");
HRESULT hr = MyGoodFunction(&bstrLeak);
若要避免外泄,請先在現有 CComBSTR
物件上呼叫 Empty
方法,再將位址傳遞為 [out] 參數。
請注意,如果函式的參數是 [in, out] ,則相同的程式碼不會造成洩漏。