ATL基础BSTR CComBSTR SysAllocString
2014-10-31 10:28
274 查看
ATL基础BSTR CComBSTR SysAllocString
原创地址:http://bbs.pediy.com/showthread.php?t=125705
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 来得简单。
原创地址:http://bbs.pediy.com/showthread.php?t=125705
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 来得简单。
相关文章推荐
- ATL基础BSTR CComBSTR SysAllocString
- 【转】ATL基础BSTR CComBSTR SysAllocString
- bstr_t 与 SysAllocString 的疑惑
- WineAPI SysAllocString
- wchar_t,char,string,CString,BSTR,CComBSTR,_bstr_t,VARIANT 、_variant_t 与 COleVariant相互转换
- SysAllocString,SysFreeString
- 未分类--Windows API--SysAllocString
- 理解COM字符串数据类型BSTR 、CComBSTR类
- C#基础之String篇
- java基础--特殊的String
- CString、char、string、int、_bstr_t、CTime、COleDateTime相互转换&判断一个字符串是一个浮点数
- java基础--特殊的String
- CString、char*、string、_bstr_t、CTime、DateTime相互转换(转)
- CString、char*、string、_bstr_t、CTime、DateTime相互转换
- _bstr_t 和CComBSTR
- Convert From BSTR to String
- Manual SysDateLookup on a FormStringControl
- Sys.StringBuilder里的Bug
- JAVA基础,String,int互转
- int 和 String 互相转换的多种方法-Java基础-Java-编程开发