字符串

来源:互联网 发布:客户无忧软件下载 编辑:程序博客网 时间:2024/06/05 00:55

COM的基本字符串类型:OLECHAR和Basic String (BSTR)。

一、从OLECHAR开始

OLECHAR(定义在<wtypes.h>)是C++里的标准COM字符数据类型。COM组件中有很大一部分方法希望他们的接受的字符串参数是OLECHAR数组。

OLECHAR会根据你的目标运行平台转换为char (ANSI) 或wchar_t (Unicode)字符。详见理解OLECHAR

二、BSTR、_bstr_t与CComBSTR

BSTR是带有字符串长度信息的以NULL结尾的一个OLECHAR数组。

BSTR是32位指针。LP表示长指针,在win16下有长指针(LP)和短指针(P)的区别,而在win32下是没有区别的,都是32位,所以LP和P是等价的

typedef OLECHAR *BSTR;//<wtypes.h>

CComBSTR是COM对BSTR的封装。它不需要手动去管理BSTR字符串的申请和释放。

_bstr_t是C++对BSTR的封装

参考COM中的OLECHAR ,BSTR和CComBSTR的理解和应用

三、CString和LPCTSTR

CString是一个动态TCHAR数组,BSTR是一种专有格式的字符串(需要用系统提供的函数来操纵,见上文),LPCTSTR只是一个常量的TCHAR指针。

3.1 先要了解一下TCHAR

为了了解TCHAR,则还要先了解ANSI和Unicode标准。ANSI, UNICODE,UTF8编码的区别

还要了解一下LPSTR与LPCSTR:

vc++中各种字符串的表示法首先char* 是指向ANSI字符数组的指针,其中每个字符占据8位(有效数据是除掉最高位的其他7位),这里保持了与传统的C,C++的兼容。LP的含义是长指针(long pointer)。LPSTR是一个指向以‘\0’结尾的ANSI字符数组的指针,与char*可以互换使用,在win32中较多地使用LPSTR。而LPCSTR中增加的‘C’的含义是“CONSTANT”(常量),表明这种数据类型的实例不能被使用它的API函数改变,除此之外,它与LPSTR是等同的。总结:1.LP表示长指针,在win16下有长指针(LP)和短指针(P)的区别,而在win32下是没有区别的,都是32位.所以这里的LP和P是等价的.2.C表示const

为了满足程序代码国际化的需要,业界推出了Unicode标准,它提供了一种简单和一致的表达字符串的方法,所有字符都是16位的双字节值;
其数量也可以满足差不多世界上所有书面语言字符的编码需求,开发程序时使用Unicode(类型为wchar_t)是一种被鼓励的做法。

由此产生了LPWSTR与LPCWSTR,它们的含义类似于LPSTR与LPCSTR,只是字符数据是16位的wchar_t而不是char。

然后为了实现两种编码的通用,提出了TCHAR的定义:

如果定义_UNICODE,声明如下:typedef wchar_t TCHAR;如果没有定义_UNICODE,则声明如下:typedef char TCHAR;

也就是说,TCHAR实际上就是一个宏定义。T前缀表示,在采用Unicode方式编译时是wchar_t,在普通时编译成char.(类似地,LPTSTR和LPCTSTR中T的含义就是每个字符是这样的TCHAR。)

LPCTSTR:#ifdef _UNICODE    typedef const wchar_t * LPCTSTR;#else    typedef const char * LPCTSTR;#endif

3.2 CString

CString类中的字符就是被声明为TCHAR类型的,它提供了一个封装好的类供用户方便地使用。

CString类还封装了很多方法,重载了支持很多类型字符串格式的构造函数和运算符

3.2.1 CString、CStringA 和 CStringW

Visual C++.NET中将CStringT作为ATL和MFC的共享的“一般”字符串类,它有CString、CStringA和CStringW三种形式,分别操作不同字符类型的字符串。这些字符类型是TCHAR、char和wchar_t。
TCHAR在Unicode平台中等同于WCHAR(16位 Unicode字符),在ANSI中等价于char。
wchar_t通常定义为unsigned short。由于CString在MFC应用程序中经常用到,这里不再重复。

四、VARIANT、COleVariant 和_variant_t

在OLE、ActiveX和COM中,VARIANT数据类型提供了一种非常有效的机制,由于它既包含了数据本身,也包含了数据的类型,因而它可以实现各种不同的自动化数据的传输。
下面让我们来看看OAIDL.H文件中VARIANT定义的一个简化版:

struct tagVARIANT {VARTYPE vt;union {short iVal; // VT_I2.long lVal; // VT_I4.float fltVal; // VT_R4.double dblVal; // VT_R8.DATE date; // VT_DATE.BSTR bstrVal; // VT_BSTR.short * piVal; // VT_BYREF|VT_I2.long * plVal; // VT_BYREF|VT_I4.float * pfltVal; // VT_BYREF|VT_R4.double * pdblVal; // VT_BYREF|VT_R8.DATE * pdate; // VT_BYREF|VT_DATE.BSTR * pbstrVal; // VT_BYREF|VT_BSTR.};};

显然,VARIANT类型是一个C结构,它包含了一个类型成员vt、一些保留字节以及一个大的union类型。
例如,如果vt为VT_I2,那么我们可以从iVal中读出VARIANT的值。
同样,当给一个VARIANT变量赋值时,也要先指明其类型。例如:

VARIANT va;:: VariantInit(&va); // 初始化int a = 2002;va.vt = VT_I4; // 指明long数据类型va.lVal = a; // 赋值

为了方便处理VARIANT类型的变量,Windows还提供了这样一些非常有用的函数:

VariantInit —— 将变量初始化为VT_EMPTY;VariantClear —— 消除并初始化VARIANT;VariantChangeType —— 改变VARIANT的类型;VariantCopy —— 释放与目标VARIANT相连的内存并复制源VARIANT。

COleVariant类是对VARIANT结构的封装。
它的构造函数具有极为强大大的功能,当对象构造时首先调用VariantInit进行初始化,然后根据参数中的标准类型调用相应的构造函数,并使用VariantCopy进行转换赋值操作;当VARIANT对象不在有效范围时,它的析构函数就会被自动调用,由于析构函数调用了VariantClear,因而相应的内存就会被自动清除。
除此之外,COleVariant的赋值操作符在与 VARIANT类型转换中为我们提供极大的方便。例如下面的代码:

COleVariant v1(”This is a test”); // 直接构造COleVariant v2 = “This is a test”;// 结果是VT_BSTR类型,值为”This is a test”COleVariant v3((long)2002);COleVariant v4 = (long)2002;// 结果是VT_I4类型,值为2002

_variant_t是一个用于COM的VARIANT类,它的功能与COleVariant相似。不过在Visual C++.NET的MFC应用程序中使用时需要在代码文件前面添加下列两句:

#include “comutil.h”#pragma comment( lib, “comsupp.lib” )

五、相互转换

各种类型格式的转换可以参考这篇文章。

里面也是copy了三篇文章,很全(但是脉络不太清晰)。

0 0
原创粉丝点击