1.1 BSTR分析
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
语言方式的类型定义方式,这种定义方式提高了
BSTR
在
C++
的应用效率,但是也带来了很多的潜在风险,它使程序员失去了利用编译器检查潜在问题的机会。
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 FunctionsDescriptionsSysAllocStringCreates 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.
BSTR详解三 - BSTR使用注意事项2007-9-7 21:34:12
1.1 BSTR分析
BSTR
设计对于
C++
程序员好坏参半。
1.2 BSTR使用基本规则
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);
}
|