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
我风 阅读(1337)
评论(0) 编辑 收藏 引用