共用方式為


利用 CComBSTR

ATL 類別 CComBSTRBSTR 資料型別周圍的包裝函式。 當 CComBSTR 非常實用的工具時,不需要注意的數種情況。

  • 轉換問題。

  • 範圍問題

  • 明確釋放 CComBSTR 物件

  • 在迴圈中使用 CComBSTR 物件

  • 記憶體遺漏問題

轉換問題。

雖然許多 CComBSTR 方法會自動轉換成 ANSI 字串引數到 Unicode,方法永遠都會傳回 Unicode 格式字串。 若要轉換輸出至 ANSI 字串,請使用 ATL 轉換類別。 如需轉換 ATL 類別的詳細資訊,請參閱 ATL 和 MFC 字串轉換巨集

bdyd6xz6.collapse_all(zh-tw,VS.110).gif範例

// 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 修改物件,請使用寬字元字串。 這會減少不必要的轉換。

bdyd6xz6.collapse_all(zh-tw,VS.110).gif範例

// 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 字串,這可能會造成問題,因為,指標會參考已經釋放的記憶體。 在這些情況下,請使用 複本 方法,如下所示。

bdyd6xz6.collapse_all(zh-tw,VS.110).gif範例

// 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 物件無效。

bdyd6xz6.collapse_all(zh-tw,VS.110).gif範例

// 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 提供更好的效能。

bdyd6xz6.collapse_all(zh-tw,VS.110).gif範例

// 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]

請參閱

參考

CStringT 類別

wstring

其他資源

ATL 概念

字串轉換巨集