ComBSTR的使用
用 CComBSTR 进行编程
ATL 类 CComBSTR 提供对 BSTR 数据类型的包装。尽管 CComBSTR 是一个有用的工具,但有一些情况需要特别小心。
转换问题
虽然一些 CComBSTR 方法自动将 ANSI 字符串参数转换为 Unicode,但这些方法总是返回 Unicode 格式的字符串。若要将输出字符串转换回 ANSI,请使用 ATL 转换类。有关 ATL 转换类的更多信息,请参见 ATL 和 MFC 字符串转换宏。
示例
// Declare a CComBSTR object. Although the argument is ANSI,
// the constructor converts it into UNICODE.
CComBSTR bstrMyString( "Hello World" );
// Convert the string into an ANSI string
CW2CT szMyString( bstrMyString );
// Display the ANSI string
MessageBox( NULL, szMyString, _T("String Test"), MB_OK );
如果使用字符串来修改 CComBSTR 对象,请使用宽字符字符串。这会减少不必要的转换。
示例
// The following converts the ANSI string to Unicode
CComBSTR bstr("Test");
// The following uses a Unicode string at compile time
CComBSTR bstr(L"Test");
范围问题
与任何功能完善的类一样,CComBSTR 在超出范围时将释放其资源。如果函数返回指向 CComBSTR 字符串的指针,这会引起问题,因为指针将引用已经释放的内存。在这种情况下,请使用Copy 方法,如下所示。
示例
// The wrong way to do it
BSTR * MyBadFunction()
{
// Define a pointer to a BSTR
BSTR * bstrStringPtr;
// Create the CComBSTR object
CComBSTR bstrString("Hello World");
// Convert the string to uppercase
bstrString.ToUpper();
// Assign the pointer
* bstrStringPtr = bstrString;
// Return the pointer. ** Bad thing to do **
return bstrStringPtr;
}
// The correct way to do it
HRESULT MyGoodFunction(/*[out]*/ BSTR* bstrStringPtr)
{
// Create the CComBSTR object
CComBSTR bstrString("Hello World");
// Convert the string to uppercase
bstrString.ToUpper();
// Return a copy of the string.
return bstrString.CopyTo(bstrStringPtr);
}
显式释放 CComBSTR 对象
在对象超出范围之前,可以显式释放包含在 CComBSTR 对象中的字符串。如果字符串被释放,则 CComBSTR 对象无效。
示例
// Declare a CComBSTR object
CComBSTR bstrMyString( "Hello World" );
// Free the string explicitly
::SysFreeString(bstrMyString);
// The string will be freed a second time
// when the CComBSTR object goes out of scope,
// which is unnecessary.
在循环中使用 CComBSTR 对象
在 CComBSTR 类分配缓冲区来执行某些运算时,如 += 运算符或 Append 方法,建议不要在紧密型循环内执行字符串操作。在这种情况下,CStringT 可提供更好的性能。
示例
// This is not an efficient way
// to use a CComBSTR object.
CComBSTR bstrMyString;
while (bstrMyString.Length()<1000)
bstrMyString.Append(L"*");
内存泄漏问题
将已初始化的 CComBSTR 的地址作为 [out] 参数传递到函数会导致内存泄漏。
在下面的示例中,在函数 OutString
替换为了保存字符串 "Initialized"
而分配的字符串时,该字符串被泄漏。
CComBSTR bstrLeak(L"Initialized");
HRESULT hr = OutString(&bstrLeak);
若要避免泄漏,请在作为 [out] 参数传递地址之前,对现有的 CComBSTR 对象调用 Empty 方法。
请注意,如果函数的参数是 [in, out],则同样的代码将不会导致泄漏
ComBSTR的使用的更多相关文章
- MSXML使用教程
在DOM接口规范中,有四个基本的接口:Document,Node,NodeList以及NamedNodeMap.在这四个基本接口中,Document接口是对文档进行操作的入口,它是从Node接口继承过 ...
- 欧拉工程第51题:Prime digit replacements
题目链接 题目: 通过置换*3的第一位得到的9个数中,有六个是质数:13,23,43,53,73和83. 通过用同样的数字置换56**3的第三位和第四位,这个五位数是第一个能够得到七个质数的数字,得到 ...
- sql查询行转列
昨天下午碰到一个需求,一个大约30万行的表,其中有很多重复行,在这些行中某些字段值是不重复的. 比如有ID,NAME,CONTRACT_id,SALES,PRODUCT等,除了PRODUCT字段,其余 ...
随机推荐
- MFC onchar()
为什么在CView类中可以对ON_CHAR进行相应,添加消息处理函数onchar就可以了,但是在CDialog中要对ON_CHAR相应,直接添加不行? CView相当于Text控件,你可以在Text控 ...
- u-boot.lds文件简介
可执行文件由许多链接在一起的对象文件组成.对象文件有许多节,如文本.数据.init 数据.bss等.这些对象文件都是由一个称为 链接器脚本(*lds)的文件链接并装入的.这个链接器脚本的功能是将输入对 ...
- 让人一看就懂的excel相对引用和绝对引用案例解析
http://www.ittribalwo.com/article/2831.html 内容提要:本文的excel相对引用和绝对引用.混合引用的使用方法案例截选自<Excel效率手册 早做完,不 ...
- sendfile Linux函数
现在流行的 web 服务器里面都提供sendfile 选项用来提高服务器性能,那到底 sendfile 是什么,怎么影响性能的呢? sendfile 实际上是 Linux 2.0+ 以后的推出的一个系 ...
- Java中的一些性能监控和故障分析工具
这些工具都在JDK的bin目录下,如果配置了java的环境变量,可以直接在命令行里调用这些小工具 jps 查看java进程信息 jstat java虚拟机状态监控工具 jstat -gc(或 -gcn ...
- vi 撤销操作
'u' : 撤销上一个编辑操作 'ctrl + r' : 恢复,即回退前一个命令 'U' : 行撤销,撤销所有在前一个编辑行上的操作
- Centos 创建 docker项目
从gitlab上下载一个docker-compose.yml文件. wget -o docker-compose.yml \ https://raw.githubusercontent.com/sam ...
- mysql补充(2)常用sql语句
补充:MySQL数据库 详解 常用的Mysql数据库操作语句大全 1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码 1.连接到本机上的MYSQL.首先打开DOS窗口,然后 ...
- MFC如何获取控件相对于窗口的左边,以及鼠标相对于控件的位置
CRect rect; CWnd *pWnd = GetDlgItem(IDC_STATIC_PIC); pWnd->GetWindowRect(&rect); ScreenToClie ...
- POJ3150 Candies【差分约束】
During the kindergarten days, flymouse was the monitor of his class. Occasionally the head-teacher b ...