这看起来有点脱离本书的主题。但是在下一个试验中,我们将把第一章的CarInCPP转换成COM SERVER。由于CCar使用了字符数据,我们需要先了解COM的基本字符串类型:OLECHARs和Basic String (BSTR)。
事 先说明:COM的字符串操作需要一些技巧。因为COM是语言独立性的,所以我们必须应付一些问题:并不是所有的语言中的字符串都是以NULL结尾。VB中 的字符串则是预先定义长度且以NULL结尾。COM在语法上又允许C的字符数组当作接口的参数,这会让VB,VBSCRIPT还有JAVA的客户端感到困 惑。
还 不止是这样,COM逐步演变成平台独立性,更糟的是操作系统存储字符串的方式也不尽相同。WIN NT是UNICODE,但是WIN 9X不是。随着32BIT OLE的发布,COM被认为是100% UNICODE的世界。这意味着你传入COM 组件里的字符串参数应该是100%的UNICODE。
基于上述事实,COM的字符串必须被设计成让所有语言和所有操作系统都能使用的类型。这个最终的字符串类型是BSTR。在我们讨论这个事实上COM字符串类型以前,先来看看原始的OLECHAR类型。
理解OLECHAR
OLECHAR(定 义在<wtypes.h>)是C++里的标准COM字符数据类型。COM组件中有很大一部分方法希望他们的接受的字符串参数是OLECHAR 数组。OLECHAR会根据你的目标运行平台转换为char (ANSI) 或wchar_t (Unicode)字符。
// OLECHAR expands to wchar_t or char.
// Below,WCHAR is a simple typedef to wchar_t.
#if defined(_WIN32) && !defined(OLE2ANSI)
typedef WCHAR OLECHAR;
#else
typedef char OLECHAR;
#endif
OLECHAR 用于存储一个COM字符(如:字符“H”)。如果你需要OLECHAR的数组,你可以声明一个LPOLESTR(OLECHAR指针)变量,如果字符串不 允许修改,用LPCOLESTR(const OLECHAR指针)。这些typedefs将被转换为char* 或 wchar_t*(有或没有const关键字):
// An array of OLECHARs can be defined with the LPOLESTR or LPCOLESTR
// typedefs.
#if defined(_WIN32) && !defined(OLE2ANSI)
typedef OLECHAR* LPOLESTR;
typedef const OLECHAR* LPCOLESTR;
#else
typedef LPSTR LPOLESTR;
typedef LPCSTR LPCOLESTR;
#endif
在我们学习如何使用新的类型创建COM字符串之前,我们还有需要熟悉OLESTR宏。那么OLESTR宏是用来干什么的呢?有些平台是使用UNICODE而另一些不是。我们在字符串加L来创建UNICODE版本,我们同样可以以这种方式创建字符数组:
// This will only work on Unicode savvy platforms.
OLECHAR* pOLEStr; // Could use LPOLESTR or LPCOLESTR as well.
pOLEStr = L"Fred Flintstone";
如 果我们这样做,在非UNICODE的WIN9X就会出现问题。另一种方式就是在字符串前不加L来创建CHAR类型的OLECHAR字符数组。这种方式可以 工作在所有的平台,但在NT的平台上会在系统内进行转换(这拖慢了速度)。对付这个问题,编译时如果在UNICODE的平台则在字符串前加L,否则不加:
// OLESTR will conditionally expand to a Unicode or char* string.
#if defined(_WIN32) && !defined(OLE2ANSI)
#define OLESTR(str) L##str
else
#define OLESTR(str) str
#endif
永远使用OLESTR宏初始化OLECHAR数组,这样所有人都开心。嗯,几乎所有的人。记住,如果你在自定义接口中的方式里使用OLECHAR数组,那么你的COM对象只有C或C++的客户端可以使用。
原文链接:https://www.f2er.com/vb/261614.html