wchar_t/OLECHAR)。wchar_t 為 2 位元組 0)。typedef OLECHAR* BSTR;、typedef OLECHAR* LPOLESTR;。
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); // 必須配對呼叫,避免記憶體洩漏
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 未釋放 → 洩漏
#include
USES_CONVERSION; // 宣告臨時緩衝區
// TCHAR → OLECHAR
LPOLESTR oleStr = T2OLE(tcharStr); // 非常數
LPCOLESTR oleCStr = T2COLE(tcharStr); // 常數
// OLECHAR → TCHAR
LPTSTR tStr = OLE2T(oleStr);
LPCTSTR tCStr = OLE2CT(oleCStr);
巨集內部使用 alloca 分配棧上緩衝,函式返回自動釋放,適合短暫轉換。
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 回傳指標供後續使用,實際緩衝已釋放。T2OLE 呼叫 MultiByteToWideChar(CP_ACP),Unicode 專案直接複製,確保專案設定一致。BSTR 為 COM 字串標準,核心原則:誰分配誰釋放。優先使用 _bstr_t (RAII) 或 CString::AllocSysString 簡化管理;短暫轉換用 ATL 巨集;嚴禁混淆所有權導致洩漏或崩潰。