COM 開發中最讓人頭痛的莫過於各種字串、變體與陣列類型的相互轉換。本文系統整理 BSTR 族、VARIANT 族、SAFEARRAY 的定義、記憶體管理規則、封裝類別用法與常見陷阱,附程式碼範例。
typedef OLECHAR *BSTR; // OLECHAR = WCHAR = wchar_t
// 記憶體佈局:前 4 位元組 = 字串位元組長度(不含結尾 null),後接 Unicode 字元陣列,雙 null 結尾
| 函式 | 用途 |
|---|---|
SysAllocString | 配置 BSTR 並複製內容 |
SysReAllocString | 重新配置並複製 |
SysAllocStringLen | 指定長度配置 |
SysFreeString | 釋放 BSTR |
SysStringLen | 取得字元數 |
SysStringByteLen | 取得位元組長度(前綴值) |
Detach() 釋放擁有權、Attach() 取得擁有權、Assign() 複製內容、GetAddress() 取得指標供輸出參數填寫。vt 欄位指示聯合體中有效欄位類型(VT_I4、VT_BSTR、VT_ARRAY、VT_DISPATCH 等)。VariantInit() 初始化,用畢 VariantClear() 釋放。VT_I2、VT_I4 等)直接儲存於結構,型別改變會導致指標失效。VT_BYREF 僅持有指標,記憶體由呼叫者管理。VT_BSTR 需 SysAllocString/SysFreeString 配對。VT_ARRAY 需 SafeArrayCreate/SafeArrayDestroy 配對。VT_DISPATCH/VT_UNKNOWN 需手動 AddRef/Release。IRecordInfo。VariantInit/Clear、記憶體、參考計數,介面簡潔,建議優先使用。SafeArrayAllocDescriptor + 手動設定 bounds + pvData 指向現有陣列。SafeArrayAllocDescriptor + SafeArrayAllocData + SafeArrayAccessData 寫入。lDimension[1]=row, [0]=col。SafeArrayCreate(VT_I4, 1, &bound) / SafeArrayCreate(VT_I4, 2, bounds)。SafeArrayCreateEx + IRecordInfo。SafeArrayAccessData 取得直接指標(高效,需成對 UnaccessData)。SafeArrayGetElement/PutElement 逐元素存取(安全,支援多維)。