BSTR

化學化工 (Batch Stirred Tank Reactor)BSTR是"Batch Stirred Tank Reactor"的縮寫間歇攪拌反應器。

BSTR

概述

它被描述成一個與自動化相兼容的類型,由於作業系統提供相應的API函式(如SysAllocString)來管理它以及一些默認的調度代碼。因此BSTR實際上就是一個COM字元串,但它卻在自動化技術以外的多種場合下得到廣泛使用。

化學化工

BSTR是"Batch Stirred Tank Reactor"的縮寫
間歇攪拌反應器

C++

為什麼需要BSTR

COM是一種跨程式語言的平台,需要提供語言無關的數據類型。多數程式語言有自己的字元串表示。
●C++ 字元串是以0結束的ASCII或Unicode字元數組
●Visual Basic字元串是一個ASCII字元數組加上表示長度的前綴。
●Java字元串是以0結束的Unicode字元數組。
需要定義一種通用的字元串類型,可以很容易的匹配到不同程式語言。C++中,就是BSTR

什麼是BSTR

BSTR是“Basic STRing”的簡稱,微軟在COM/OLE中定義的標準字元串數據類型
對於C++,Windows頭檔案wtypes.h中定義如下:
typedef wchar_t WCHAR;
typedef WCHAR OLECHAR;
typedef OLECHAR __RPC_FAR *BSTR;;
使用以Null結尾的簡單字元串在COM component間傳遞不太方便。因此,標準BSTR是一個有長度前綴和null結束符的OLECHAR數組BSTR的前4位元組是一個表示字元串長度的前綴。BSTR長度域的值是字元串的位元組數,並且不包括0結束符。
由於是Unicode串,所以字元數是位元組數的一半。這種方式的優點是允許程式設計師在BSTR串中間嵌入NULL字元。但是,BSTR的前四個位元組表示長度,而OLECHAR數組的前四位元組表示前兩個字元。這種情況下,對於C++程式,如何實現BSTR和OLECHAR的交換?答案是COM提供了兩個BSTR分配用的API:SysAllocString / SysReallocString。函式返回的指針指向BSTR的第一個字元,而不是BSTR在記憶體的第一個位元組。

什麼時候使用BSTR

只有在你不得不用的時候。
使用BSTR一般有以下幾種情況:
●COM interface接口定義,並且不希望額外提供custom marshaling庫(MDIL生成或開發人員自己訂製),必須使用BSTR傳遞字元串。使用C/C++類型的字元串在COM DLL傳遞字元串,表面上可以使用,但違背了COM的基本規則,並且給以後的擴展留下了隱患。例如,把一個In-process COM Object(簡單說COM DLL)改成out-of-process object(COM EXE)。理論上,客戶端的代碼應該不做任何改變。但如果是用了C/C++字元串,又希望只使用系統的automation mashaller(Oleaut32.dll),就會出錯。
●如果可以提供custom marshaling,也推薦使用BSTR。
●客戶要求接口必須使用BSTR,和客戶討論後,不能修改。
●使用的外部庫的接口使用BSTR
不使用的情況:
不推薦在IDL結構體中定義BSTR成員,會給結構體的複製和釋放帶來麻煩。最好直接使用限定最大長度的TCHAR數組。如果確實需要傳遞變長字元串,BSTR應該被定義成獨立的參數或者使用獨立的get/set接口。
儘可能縮小的BSTR及相關類型的作用域範圍。類的成員變數和函式參數不使用BSTR。局部變數要儘快釋放類的內部不使用BSTR。代碼處理邏輯中只在接口直接相關部分使用BSTR。接收到一個BSTR時,儘量立刻變成C/C++的字元串副本進行處理。在需要傳遞BSTR參數前產生BSTR,用過立即釋放。
字元串相關類型的推薦選擇順序
優先權類型說明
最高stl::string/wstring●功能最完善,可移植性最好。

CString如果編碼規範限制使用STL的時候,推薦CString。 ●VC 6的版本很不完善。.Net有明顯改進,需要進一步研究

C/C++ basic type
(TCHAR* / char* /
LPTSTR / LPCTSTR / TCHAR[])
●在結構體中,優先使用指定最大長度的字元數組。 ●效率最好

CComBSTR/ _bstr_t●在必須使用BSTR時的優先選擇。
●在ATL(COM component)工程或者工程中必須使用ATL中,優先選擇CComBSTR。一般Exe/dll如果_bstr_t能滿足要求,優先使用_bstr_t。
●對於VC6,使用_bstr_t一定要慎重,最好只用作簡單臨時變數保存調被調用函式的傳入參數。因為_bstrt_t不能支持一些關鍵性操作,比如Detach。
● 對於VC++ .Net推薦使用_bstr_t,它是C++擴展,不需要額外包含ATL的檔案。
最低BSTR● COM接口

BSTR利弊

BSTR設計對於C++程式設計師好壞參半。
一方面,BSTR可以被用於大多數需要OLECHAR數組作為參數的函式。
另一方面,不能用熟悉的C/C++函式進行對BSTR的分配、釋放和處理,例如malloc, free, new, delete, lstrcat, and lstrlen 等函式不能用於處理BSTR。就像對接口指針和類指針的處理不一樣,對BSTR的處理和對TCHAR*的處理也不一樣。BSTR是一種C語言方式的類型定義方式,這種定義方式提高了BSTR在C++的套用效率,但是也帶來了很多的潛在風險,它使程式設計師失去了利用編譯器檢查潛在問題的機會。

BSTR使用規則

●在對BSTR進行讀取操作的時候,可以把BSTR看作OLECHAR數組。BSTR可以用於const wchar_t*(LPCTSTR/ LPCWSTR/ cosnt TCHAR*/ cosnt WCHAR* in Unicode project),不能用於需要wchar_t* (LPTSTR/ LPWSTR/ TCHAR*/ WCHAR* in Unicode project)的地方。
如果有相應的BSTR處理函式,必須使用BSTR處理函式,不要使用普通字元串函式。特別是一個BSTR包含多個字元串(也就是,包含多個0結束符)的情況。在對BSTR進行修改(包括創建和釋放時),必須使用BSTR的專用函式。主要要保證對字元長度前綴的正確修改。不要直接讀取BSTR的長度域,應該使用BSTR處理函式計算長度。
String Manipulation Functions Descriptions
SysAllocStringCreates and initializes a string.
SysAllocStringByteLenCreates a zero-terminated string of a specified length.
SysAllocStringLenCreates a string of a specified length.
SysFreeStringFrees a previously created string.
SysReAllocStringChanges the size and value of a string.
SysReAllocStringLenChanges the size of an existing string.
SysStringByteLenReturns the length of a string in bytes.
SysStringLenReturns the length of a string.

●NULL是BSTR的有效值。按照約定,它可以被看作含有0個字元的字元串。BSTR變數必須等於NULL,或者正確分配的BSTR指針。在改變BSTR變數的之前,必須釋放原來指向的BSTR。不要把BSTR直接初始化成常量字元指針,例如,BSTR bs = L””。
●Automation會cache BSTR使用的空間,以提高SysAllocString/SysFreeString 的性能,會給測試發現問題帶來困難。如果可能推薦在調試時使用Compuware DevPartner 7.x及更高版本的工具。

相關詞條

相關搜尋

熱門詞條

聯絡我們