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);
}
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章