BSTR詳解三 - BSTR使用注意事項

BSTR詳解三 - BSTR使用注意事項

2007-9-7 21:34:12

 

 

BSTR設計對於C++程序員好壞參半。
<script language="JavaScript" src="/js/banner_andyfans_com.js" type="text/javascript"></script> <script language="JavaScript" src="/js/google_ads.js" type="text/javascript"></script>
一方面,BSTR可以被用於大多數需要OLECHAR數組作爲參數的函數。另一方面,不能用熟悉的C/C++函數進行對BSTR的分配、釋放和處理,例如malloc, free, new, delete, lstrcat, and lstrlen 等函數不能用於處理BSTR。就像對接口指針和類指針的處理不一樣,對BSTR的處理和對TCHAR*的處理也不一樣。BSTR是一種C語言方式的類型定義方式,這種定義方式提高了BSTRC++的應用效率,但是也帶來了很多的潛在風險,它使程序員失去了利用編譯器檢查潛在問題的機會。
1.2      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
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.
 
  • NULLBSTR的有效值。 <script language="javascript" src="/js/google_ads_300_250.js" type="text/javascript"></script> 按照約定,它可以被看作含有0個字符的字符串。BSTR變量必須等於NULL,或者正確分配的BSTR指針。在改變BSTR變量的之前,必須釋放原來指向的BSTR不要把BSTR直接初始化成常量字符指針,例如,BSTR bs = L””
  • Automationcache BSTR使用的空間,以提高SysAllocString/SysFreeString 的性能,會給測試發現問題帶來困難。如果可能推薦在調試時使用Compuware DevPartner 7.x及更高版本的工具。
 
1.3      BSTR參數使用
多數時候,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);
}
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章