![]() |
使用“_t”将ansi转换成“一般”类型字符串,使用“l”将ansi转换成
使用“_T”将ANSI转换成“一般”类型字符串,使用“L”将ANSI转换成
Unicode,而在托管C++环境中还可使用S将ANSI字符串转换成String*对象。例如: |
回复: 使用“_t”将ansi转换成“一般”类型字符串,使用“l”将ansi转换成
关于BSTR数据类型
1.COM字符串类型
字符串的长度可能互不相同,因此跨COM边界传输特定的字符串时,需要确定它的长度,而且,字符串有时需要分配内存。 2.Unicode和ANSI数据类型 3.OLECHAR,LPOLESTR,LPCOLESTR COM的基本字符数据类型是OLECHAR,与平台无关的字符表示法。在创建该字符集时,OLECHAR的基本数据类型随操作系统的不同而不同。如今最流行的COM平台是基于Win32_API的,而且基于此, OLECHAR就是wchar_t的typedef。 w表示它是Unicode字符。 LPOLESTR是OLECHAR*的typedef, LPCOLESTR是同一种数据类型的const声明。 4.处理LPOLESTR 如果你试图将字符串值赋给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() 4.是否执行Unicode编译 实际上在默认情况下,ATL向导既创建了ANSI配置,又创建了Unicode配置,这使你能够一种格式或两种格式编译及发布组件服务程序,你只需坚持使用TCHAR数据类型,以便你的代码可以兼容两种字符集。 5.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来制定具体内容。 6.使用BSTR处理不同大小的字符串。 由于存在内存方面的问题,因此使用BSTR数据类型,BSTR就是指向OLECHAR字符串的指针,可以利用字符串的长度区分BSTR,该长度不包括最后的null结尾符,而且在字符串指针之前的4个字节里指定。由于它是Unicode字符串,所以每个字符占用2个字节,与LPOLESTR结尾方式一样,BSTR也必须以null结尾。BSTR避免了LPOLESTR的缺陷,因为它的长度是显示指定的,所以null字符也可嵌入到BSTR中,所以BSTR可被用于发送二进制数据和简单字符串。由于BSTR具有特殊结构,因此增加了一些特殊的API函数来处理BSTR.创建和销毁BSTR时调用这些函数。 (BSTR就是LPOLESTR指针,并且在指针的前面加上4个字节来表示大小) 7.处理BSTR的常用API函数。 应该使用SysAllocString()和SysFreeString()来管理BSTR类型 声明如下: BSTR SysAllocString(const OLECHAR *szSource); 反之,使用SysAllocStringLen()来指定结果BSTR的长度。 所有的BSTR都必须使用SysFreeString()释放。否则会造成内存泄漏。 8.跨COM边界的字符串内存管理。 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 9.字符串转换函数 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() 10.CComBSTR(CComBSTR封装了BSTR) 如果在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()函数用于复制字符串。 11._bstr_t _bstr_t保持内部的引用计数 _bstr_t是由#import指令自动添加的。与CComBSTR的最大区别是保持了一个内部引用。另一个区别是_bstr_t要求异常处理,ATL项目不会包括异常处理,因此_bstr_t更适合于COM客户程序,_bstr_t的定义与实现位于comutil.h中。 一个通用的原则是:_bstr_t类应用于COM客户程序,而CComBSTR应用于ATL服务器程序。 12.其它数据类型 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**。 Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=492384 |
所有的时间均为北京时间。 现在的时间是 07:10 PM. |