首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

OLE 字串 (BSTR) 完整操作指南:分配、長度、釋放與轉換

     編輯:關於VC++

BSTR 結構定義

  • 32 位元組長度前綴(位於字串指標前 4 位元組)。
  • 雙位元組寬字元內容(wchar_t/OLECHAR)。
  • 雙重 NULL 結尾(單一 wchar_t 為 2 位元組 0)。
  • 類型定義:typedef OLECHAR* BSTR;、typedef OLECHAR* LPOLESTR;。

核心 API 操作

分配


BSTR bs = SysAllocString(L"Text");        // 完整複製
BSTR bs = SysAllocStringLen(L"Text", 2);  // 指定長度 "Te"
BSTR bs = SysAllocStringLen(L"Text", 6);  // 超過長度:補 '\0' + 隨機資料
BOOL f = SysReAllocString(&bs, L"NewText"); // 重新分配並賦值

取得長度


UINT len = SysStringLen(bs); // 字元數(不含結尾 NULL)

釋放


SysFreeString(bs); // 必須配對呼叫,避免記憶體洩漏

轉換策略與陷阱

1. 使用 _bstr_t (推薦)


BSTR tmp;
pObj->get_String(&tmp);
_bstr_t wrapper(tmp, FALSE); // FALSE = 不取得所有權,析構時不釋放 tmp
SetDlgItemText(IDC_EDIT, wrapper); // 隱含轉換至 LPCTSTR

// 錯誤寫法:直接賦值導致雙重釋放
_bstr_t wrapper;
wrapper = tmp; // 內部 SysAllocString 複製,原 tmp 未釋放 → 洩漏

2. 使用 ATL/MFC 轉換巨集


#include 
USES_CONVERSION; // 宣告臨時緩衝區

// TCHAR → OLECHAR
LPOLESTR oleStr = T2OLE(tcharStr);    // 非常數
LPCOLESTR oleCStr = T2COLE(tcharStr); // 常數

// OLECHAR → TCHAR
LPTSTR tStr = OLE2T(oleStr);
LPCTSTR tCStr = OLE2CT(oleCStr);

巨集內部使用 alloca 分配棧上緩衝,函式返回自動釋放,適合短暫轉換。

3. CString 直接支援


CString str = "測試";
BSTR bstr = str.AllocSysString(); // 配置 BSTR 複本
FireEvent(&bstr);
::SysFreeString(bstr); // 必須手動釋放

記憶體管理鐵律

操作責任備註
SysAllocString / SysAllocStringLen呼叫者必須 SysFreeString
SysReAllocString呼叫者原 BSTR 自動釋放,新 BSTR 需釋放
_bstr_t 建構 (FALSE)呼叫者_bstr_t 不釋放傳入 BSTR
_bstr_t 建構 (TRUE/預設)_bstr_t析構時自動 SysFreeString
CString::AllocSysString呼叫者回傳新 BSTR,需 SysFreeString
ATL 轉換巨集 (T2OLE 等)自動 (alloca)函式作用域結束自動釋放,不可跨函式保存指標

常見錯誤與除錯

  • 雙重釋放:_bstr_t wrapper = bstr; SysFreeString(bstr); → wrapper 析構再次釋放。
  • 未釋放:AllocSysString 後忘記 SysFreeString。
  • 指標懸空:保存 T2OLE 回傳指標供後續使用,實際緩衝已釋放。
  • 編碼錯誤:ANSI 專案中 T2OLE 呼叫 MultiByteToWideChar(CP_ACP),Unicode 專案直接複製,確保專案設定一致。

總結

BSTR 為 COM 字串標準,核心原則:誰分配誰釋放。優先使用 _bstr_t (RAII) 或 CString::AllocSysString 簡化管理;短暫轉換用 ATL 巨集;嚴禁混淆所有權導致洩漏或崩潰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved