BSTR
設計對于
C++
程序員好壞參半。一方面,
BSTR
可以被用于大多數需要
OLECHAR
數組作為參數的函數。另一方面,不能用熟悉的
C/C++
函數進行對
BSTR
的分配、釋放和處理,例如
malloc, free, new, delete, lstrcat, and lstrlen
等函數不能用于處理
BSTR
。就像對接口指針和類指針的處理不一樣,對
BSTR
的處理和對
TCHAR*
的處理也不一樣。
BSTR
是一種
C
語言方式的類型定義方式,這種定義方式提高了
BSTR
在
C++
的應用效率,但是也帶來了很多的潛在風險,它使程序員失去了利用編譯器檢查潛在問題的機會。
?
-
在對
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
|
SysAllocString
|
Creates and initializes a string.
|
SysAllocStringByteLen
|
Creates a zero-terminated string of a specified length.
|
SysAllocStringLen
|
Creates a string of a specified length.
|
SysFreeString
|
Frees a previously created string.
|
SysReAllocString
|
Changes the size and value of a string.
|
SysReAllocStringLen
|
Changes the size of an existing string.
|
SysStringByteLen
|
Returns the length of a string in bytes.
|
SysStringLen
|
Returns 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
及更高版本的工具。
?
多數時候,
BSTR
是被用于函數參數。關于
BSTR
參數的使用規則是
BSTR
類型的基礎。只有熟練掌握,才能分析
warpper
類或轉換函數的正確性。
?
?
基本原則:在給
by-reference[in/out]
參數賦一個新的值前,被調用者負責釋放。其他情況,都是調用者負責釋放。
?
調用者使用
BSTR
的規則如下:
·????????
釋放被調用函數返回的
BSTR
,或者被調用函數通過
by-reference
返回的
BSTR
。
HRESULT IWebBrowser2::get_StatusText( BSTR FAR* pbstr );
//...
BSTR bstrStatus;
pBrowser->get_StatusText( &bstrStatus );
?
// shows using the Win32 function
// to freee the memory for the string:
::SysFreeString( bstrStatus );
?
·????????
釋放通過
by-value
方式傳給其他函數的
BSTR.
//.h
HRESULT IWebBrowser2::put_StatusText( BSTR bstr );
?
//.cpp
// shows using the Win32 function
// to allocate memory for the string:
BSTR bstrStatus = ::SysAllocString( L"Some text" );
if (bstrStatus == NULL)
?? return E_OUTOFMEMORY;
?
pBrowser->put_StatusText( bstrStatus );
// Free the string:
::SysFreeString( bstrStatus );
//...
?
被調用者按照如下規則處理
BSTR
:
·????????
如果一個
BSTR
參數是
by-reference
方式,在給參數賦新值之前,
Free
以前的值。如果沒有給參數賦的新值,不要
Free
傳入值。
void RefreshBSTR(BSTR& bs)
// bs is an [in/out] parameter. BSTR* is the same
{
// using the bs here
Dosomething(bs);
// if (bs is about to be updated)
ASSERT(bs != NULL);
::SysReallocString(bs, _T(“NEW STRING”));
// SysReallocString will call SysFreeString and
// SysAllocString in sequence
// If bs is only [out] parameter, SysAllocString
// should be called here.
}
?
·????????
不要
Free
通過
by-value
傳入的
BSTR
。
void SetBSTR(BSTR bs)
// bs is an [in] parameter. BSTR* is the same
{
// using the bs here
Dosomething(bs);
::SysFreeString(bs); //ERROR
}
?
·????????
不要
Free
返回給調用者的
BSTR .
BSTR GetBSTR1()
{
BSTR bs = ::SysAllocString(_T(“test”));
::SysFreeString(bs); //ERROR
return bs;
}
?
void GetBSTR2(BSTR* pBs)
{
CComBSTR bs(_T(“test”));
*pBS = (BSTR) bs; //ERROR: pBS will be freed automatically
}
?
·????????
如果需要保存傳入的
BSTR
,被調用著需要用
SysAllocString()
生成一個新的副本,并保存。輸入的
BSTR
會被調用者釋放。
void MyClass::SetBSTR(BSTR bs)
{
//BSTR m_bs;
m_bs = bs; //ERROR
m_bs = ::SysReAllocString(bs);
}
·????????
如果需要返回一個已經存儲的
BSTR
,返回
BSTR
的一個拷貝。調用者釋放返回的
BSTR
拷貝。
void MyClass::GetBSTR(BSTR* pbs)
{
//BSTR m_bs;
*pbs = m_bs; //ERROR
*pbs = ::SysAllocString(m_bs);
}
?
From: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1486367
posted on 2007-01-26 16:06
我風 閱讀(1353)
評論(0) 編輯 收藏 引用