关于BSTR数据类型
关于BSTR数据类型 - 极品垃圾 - C++博客 http://www.cppblog.com/bestcln/articles/82712.html
VC++常用数据类型及其操作详解(非常经典,共同分享) - 豆丁网http://www.docin.com/p-636830324.html
字符串的长度可能互不相同,因此跨COM边界传输特定的字符串时,需要确定它的长度,而且,字符串有时需要
分配内存。
COM的基本字符数据类型是OLECHAR,与平台无关的字符表示法。在创建该字符集时,OLECHAR的基本数据类型随操
作系统的不同而不同。如今最流行的COM平台是基于Win32_API的,而且基于此,OLECHAR就是wchar_t的typedef.
w表示它是Unicode字符。LPOLESTR是OLECHAR*的typedef,LPCOLESTR是同一种数据类型的const声明。
如果你试图将字符串值赋给LPOLESTR,则会收到编译错误,例如:
OLECHAR *olechar="A String!";//编译错误
反之,你应在这样的字符串前添加L前缀,如下所示:
LPOLESTR szMyString = L"This is a string!";
在使用printf()或ATLTRACE()时,这尤其重要(但通常被遗忘)
例如:
LPOLESTR szstr = L"Hello!";
ATLTRACE("string=%s",szstr);
编译后打印的是
string=T
显然是错误的,应该添加L前缀或OLESTR()宏,应该如下写:
ATLTRACE(L"string=%s",szstr);
或者
ATRTRACE(OLESTR("string=%s",szstr);
下面两个函数通常用来复制字符串。第一个是ANSI函数wcscpy();
第二个是ATL函数,名为ocscpy()
实际上在默认情况下,ATL向导既创建了ANSI配置,又创建了Unicode配置,这使你能够一种格式或两种格式编译
及发布组件服务程序,你只需坚持使用TCHAR数据类型,以便你的代码可以兼容两种字符集。
TCHAR是一般的字符类型。TCHAR的定义如下:
#ifdef UNICODE
typedef WCHAR TCHAT
#else
typedef char TCHAR
#endif
默认情况下,C++字符串文字为char*类型,通过在字符串前使用L前缀,可以将他们指定为宽字符。
在TCHAR*数据类型,应该使用_T,例如:
TCHAR *p_tchar = _T("this is string";
此代码将字符串赋给ANSI/UNICODE兼容格式的字符串。_T是个宏,根据UNICODE来制定具体内容。
由于存在内存方面的问题,因此使用BSTR数据类型,BSTR就是指向OLECHAR字符串的指针,可以利用字符串的长
度区分BSTR,该长度不包括最后的null结尾符,而且在字符串指针之前的4个字节里指定。由于它是Unicode字符
串,所以每个字符占用2个字节,与LPOLESTR结尾方式一样,BSTR也必须以null结尾。BSTR避免了LPOLESTR的缺
陷,因为它的长度是显示指定的,所以null字符也可嵌入到BSTR中,所以BSTR可被用于发送二进制数据和简单字
符串。由于BSTR具有特殊结构,因此增加了一些特殊的API函数来处理BSTR.创建和销毁BSTR时调用这些函数。
(BSTR就是LPOLESTR指针,并且在指针的前面加上4个字节来表示大小)
应该使用SysAllocString()和SysFreeString()来管理BSTR类型
声明如下:
BSTR SysAllocString(const OLECHAR *szSource);
反之,使用SysAllocStringLen()来指定结果BSTR的长度。
所有的BSTR都必须使用SysFreeString()释放。否则会造成内存泄漏。
BSTR没有引用计数机制
(1)在传递字符串时,服务器负责什么操作。
COM服务器程序不应该维护跨COM边界传递的变量的引用,相反,应该进行复制。
在跨COM边界传递BSTR时,服务器程序的管理原则是客户程序负责释放BSTR。无论BSTR是[in]还是[out]参数。都
将如此。在将字符串传递给客户程序时,需要服务器程序释放该字符串的唯一时候是为[in,out]参数赋信值之前
。此时,客户程序传递被分配的字符串,而服务器程序释放该字符串,然后制订一个指针,他指向新分配的字符
串的位置,而且该字符串将由客户程序释放,对于服务器程序而言,管理原则始终是创建输入和输出BSTR的copy
,而不是给现有BSTR添加另一个引用。
例如:
STDMETHOD CstrigTest::GetValue(BSTR *pResult)
{
*pResult = m_str;
return S_OK;
}
//这是不对的,虽然没有 语法错误,大违反了COM的管理规则,应该如下:
方法一:
STDMETHOD CstrigTest::GetValue(BSTR *pResult)
{
*pResult = SysAllocString(m_str);
return S_OK;
}
方法二:
STDMETHOD CstrigTest::GetValue(BSTR *pResult)
{
*pResult = m_str;
m_str = NULL;
return S_OK;
}
输入参数时原则相同。
下面是处理BSTR的指导方针:
(1)[in]参数必须由client拥有,所以,如果服务器程序应该创建copy,不应释放或更改这些参数。
(2)[out]参数由client释放。
(3)客户程序必须将NULL或释放的BSTR传递给服务器程序的[out]参数中。
(4)在服务器程序在被赋予新的BSTR值之前,[in,out]参数必须被释放。
(5)始终使用SysStringLen()获得BSTR的长度。
COM+提供了两个类函数对字符串进行封装:CComBSTR 和_bstr_t
ATL字符串转换宏(在使用任何宏之前,一定要指定USER_CONVERSION宏,否则会遇到如下编译错误:error c2065:'_lpw'undeclared
identifier)
A2BSTR A2COLE A2CW .......(很多)
例如:(使用W2A宏)
LPOLESTR szString=L"this is a string!";
char *str;
str = W2A(szString);
所有这些宏都是以ATL为基础的,在ATL中使用这些宏时,项目必须包括atlconv.h。
COM+还定义了另外两个转换函数,而且有#import指令自动包含,这两个函数都位于comutil.h文件中,并从属于_com_util名称空间,他们可以
将ANSI字符串转换成BSTR,或者反向。函数为:
ConvertStringToBSTR()
ConvertBSTRToString()
如果在BSTR超出了其作用域时没有调用SysFreeString(),则系统调用会造成内存泄漏。
CComBSTR在ATL的atlbase.h头文件中定义,因为它在一个ATL文件中定义,所以CComBSTR在ATL项目中最常用,以从COM客户程序中来回传递字符
串。
CComBSTR只有一个数据成员,名为m_str的公共BSTR。CComBSTR的用途是封装BSTR数据类型,以帮助BSTR的内存管理。还有ToUpper(),ToLower(
)等将字符串转换为特定的大小写格式。
(在构造函数种分配内存,在析构函数中释放内存)。
在赋值,实例化,删除时内存管理非常关键。
Attach()转移所有权。
必须是m_str=NULL时才能使用Attach()
Detach()用于释放所有权,
BSTR Detach()
{
BSTR s = m_str;
m_str = NULL;
return s;
}
Copy()函数用于复制字符串。
_bstr_t保持内部的引用计数
_bstr_t是由#import指令自动添加的。与CComBSTR的最大区别是保持了一个内部引用。另一个区别是_bstr_t要求异常处理,ATL项目不会包括
异常处理,因此_bstr_t更适合于COM客户程序,_bstr_t的定义与实现位于comutil.h中。
一个通用的原则是:_bstr_t类应用于COM客户程序,而CComBSTR应用于ATL服务器程序。
1.COM数据类型
COM name C++ size
Byte BYTE 8
Boolean VARIANT_BOOL 16
Double double 64
Float float 32
Integer int
Long long 32
Short short 16
String BSTR
Date DATE
Variant VARIANT
Dispatch Interface IDispatch*
Unknown Interface IUnknown*
2.VARIANT结构
3._variant_t
_variant_t是micsoft特有的,它是VARIANT的C++封装器类
4.传递数组
传递数组的类型为:SAFEARRAY**。
关于BSTR数据类型的更多相关文章
- 理解BSTR数据类型 神奇的BSTR
理解BSTR数据类型 神奇的BSTR - 深蓝的日志 - 网易博客 http://blog.163.com/pugood@126/blog/static/13441759320091111115264 ...
- VC++常用数据类型
原文地址:https://www.cnblogs.com/yincheng01/archive/2008/12/31/2213386.html 一. VC常用数据类型列表 二 ...
- VC++常用数据类型及其操作详解
原文地址:http://blog.csdn.net/ithomer/article/details/5019367 VC++常用数据类型及其操作详解 一.VC常用数据类型列表 二.常用数据类型转化 2 ...
- CString char BSTR 转换
关于字符集不一的历史原因,可以参考: UNICODE与ANSI的区别 以下是网上转载的资料.我将辅以自己的实例,说明并总结关系. 一.CString, int, string, char*之间的转换 ...
- CString-int-string-char-BSTR之间的转换
一.CString, int, string, char*之间的转换 string 转 CString CString.Format("%s", string.c_str());c ...
- ADO数据库链接
一.数据库操作准备 // --------------------------------------------------------------------------------------- ...
- VARIANT类型
VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义.struct tagVARIANT { union { ...
- ComBSTR的使用
用 CComBSTR 进行编程 Visual Studio .NET 2003 3(共 3)对本文的评价是有帮助 - 评价此主题 ATL 类 CComBSTR 提供对 BSTR 数据类型的包装 ...
- BSTR 的奥秘
初学COM,总觉得BSTR很神秘,对于这种新的数据类型,总有很多疑问,那么BSTR到底是什么类型呢? 我们可以在头文件中的定义中最终找到 wchar这个类型被定义为BSTR,那么BSTR是wchar吗 ...
随机推荐
- 关于Parse字符串为时间一次被坑经历
在Java代码中发现一个bug,就是本来更新为时间的内容更新为一些奇怪的内容,比如20819这种形式,本来更新的时间都是近期不会超过一年, 为什么会出现这种情况,非常奇怪,遂调试下代码,跟踪发现要匹配 ...
- singer页面点击歌手singer是跳转到singer-detail的设置
1.创建components/singer-detail/singer-detail.vue 2.配置动态路由: { path: ':id', name:'singer-detail', compon ...
- eclipse新建tomcat server但是总是报404的解决方法
今天在eclipse中新建了tomcat server,但是由于一些配置出了问题,导致总是出现404报错,具体情况如下 症状: tomcat在eclipse里面能正常启动,而在浏览器中访问http:/ ...
- excel保存时出现“请注意,您的文档的部分内容可能包含了文档检查器无法删除的个人信息”
这个问题的原因是由于工作簿包含宏.ActiveX控件等内容, 而Excel被设置为在保存文件时自动删除文件属性中的个人信息,因而出现该对话框.如果要避免出现这个提示,可进行如下设置: Excel 20 ...
- mysql海量数据处理步骤
本文转自https://segmentfault.com/a/1190000006158186 当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表数据 ...
- C语言 · 判定字符位置
算法训练 6-3判定字符位置 时间限制:1.0s 内存限制:512.0MB 返回给定字符串s中元音字母的首次出现位置.英语元音字母只有‘a’.‘e’.‘i’.‘o’.‘u’五个. 若 ...
- [uboot]What is MLO file?
转自:https://coherentmusings.wordpress.com/2012/09/05/what-is-mlo-file/ I have had the Beagle-xM for a ...
- Apache HttpComponents 通过代理发送HTTP请求
package org.apache.http.examples.client; import org.apache.http.HttpEntity; import org.apache.http.H ...
- Spark读取文件
spark默认读取的是hdfs上的文件. 如果读取本地文件,则需要加file:///usr/local/spark/README.md. (测试时候发现,本地文件必须在spark的安装路径内部或者平行 ...
- Phalcon的MVC框架解析
1. mvc/simple从最简单的入手吧. 把一些能及时说明白的东西写在注释里了,需要扩展的知识列在下面. public/index.php <?php $loader = new \Phal ...