首页
论坛
课程
招聘
雪    币: 347
活跃值: 活跃值 (10)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝

[原创]ATL基础BSTR CComBSTR SysAllocString

2010-11-30 09:18 10261

[原创]ATL基础BSTR CComBSTR SysAllocString

2010-11-30 09:18
10261
ATL基础BSTR CComBSTR SysAllocString

ATL提供了 BSTR 和 CComBSTR ,还有OLEAUTO32.DLL导出一个API叫SysAllocString。这些东西有什么意思?有什么用呢?

BSTR 是一个typedef,你可以理解为 typedef WCHAR* BSTR
它就是一个指针。所以
        BSTR p = L"hello";
编译是没问题的。不过不推荐这么做。因为按MSDN,BSTR应该只接收 SysAllocString 的返回值。

就是说,第一,SysAllocString 的返回值是一个 BSTR 第二,如果我们看到一个BSTR,那它应该总从由一个 SysAllocString 得到的,它总是应该用 SysFreeString 释放。

我们可以想像,SysAllocString 实际上做了一个malloc分配了一块内存,然后把内存长度放第一个DWORD,把这个DWORD后面位置作为BSTR返回。因为在BSTR减4的位置已经保存了块长度,所以对BSTR不应该用 wcslen 之类的方法来得到它的长度,要用 SysStringLen。这就是为什么不推荐用 BSTR p = L"hello"这种方法直接给BSTR赋值,因为这样得到到BSTR不符合减4位置有块长度的规范,也不能用 SysStringLen 得到长度,也不能用 SysFreeString 来释放。乱了规矩。

又一个问题,为什么需要 SysAllocString ? 我用 new 或 malloc 不行吗?因为用ATL常常是为了写COM。而COM控件是跨语言的。你用C++写一个COM控件,可能被HTML中的一个VBSCRIPT或PHP调用。你返回的那个BSTR字串可能需要在VBSCRIPT中释放。而 new 或 malloc 等常规的C++分配内存函数,都要求内存在本模块内释放。所以,SysAllocString 分析的内存,是为了支持跨模块使用,并在外地free的。

那么 CComBSTR 又是什么呢?上面讲了,BSTR只是一个指针,它太简单了。如果我要实现字串查找,字串合并等复杂的操作就要自己写代码了。于是就有了 CComBSTR这个类。它只有一个成员 BSTR m_str 但它有大量的方法函数,足够你所可能需要的所有字串操作。

最后结论:
        * BSTR 只是一个指针,要小心使用,除了 SysAllocString 不要对它赋值。
        * 如果发现一个 BSTR, 那它一定是用 SysAllocString 得到的。一定要用 SysStringLen 来得到长度。一定要用 SysFreeString 来释放它
        * 如果需要对 BSTR 做字串操作,把它变成 CComBSTR ,总有一个现成的函数直接使用。
        * 这一系列东西,都是为了COM跨模块把字串当作返回值使用的。如果一个字串只在本模块内有效,还是用 new 或 malloc 或 CString 来得简单。

HWS计划·2020安全精英夏令营来了!我们在华为松山湖欧洲小镇等你

最新回复 (5)
雪    币: 1238
活跃值: 活跃值 (43)
能力值: ( LV12,RANK:380 )
在线值:
发帖
回帖
粉丝
correy 活跃值 4 2010-11-30 17:14
2
0
顶!
学好c++!
深刻理解c++的名词与函数。
雪    币: 1115
活跃值: 活跃值 (12)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
pencil 活跃值 5 2010-11-30 19:46
3
0
谢liutaotao大牛分享
雪    币: 489
活跃值: 活跃值 (30)
能力值: ( LV13,RANK:290 )
在线值:
发帖
回帖
粉丝
guxinyi 活跃值 5 2010-12-21 13:22
4
0
不错,没怎么用过,还是标记备查.
雪    币: 172
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wangshen 活跃值 2011-2-17 16:41
5
0
好。感谢lz的分析。。
雪    币: 25
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
viviandou 活跃值 2018-11-21 14:12
6
0
请教一下,这个sysallocstring将内存分配到哪里了呢?和GlobalAlloc分配的地方是一样的吗?我感觉sysallocstring这个分配的应该不在程序的数据段上,否则按照vs中debug版本程序的说明,如果调用sysallocstring后没有调用相应的sysfreestring那么肯定会有内存泄露的信息输出,但是实际上却没有。
游客
登录 | 注册 方可回帖
返回