分享方式:


使用 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] ,則相同的程式碼不會造成洩漏。

另請參閱

概念
CStringT 類別
wstring
字串轉換巨集