设为首页 加入收藏

TOP

字符集之Unicode与字符串对象(五)
2014-11-24 00:40:12 来源: 作者: 【 】 浏览:153
Tags:字符集 Unicode 字符串 对象
ysString(BSTR*)

这两个函数提供了串与BSTR的转换。使用时须注意一点:当调用AllocSysString()后,

须调用它SysFreeString(...) ,例:

CString sBuf="TestCString";

BSTR bsBuf=sBuf.AllocSysString();

::SysFreeString(bsBuf);

bsBuf=::SysAllocString(L"Hi,I'm BSTR");

sBuf=bsBuf;

TRACE(_T("%s\n"),sBuf);

::SysFreeString(bsBuf);

2. COM 中的字符串BSTR和VARIANT
2.1. BSTR字符串类型

  很多自动化和COM接口使用BSTR来定义字符串。BSTR 是 Pascal-style 字符串(字符串长度被明确指出)和C-style字符串(字符串的长度要通过寻找结束符来计算)的混合产物。一个BSTR是一个Unicode字符串,它的长度是预先考虑的,并且它还有一个0字符作为结束标记。下面是一个BSTR的示例:06 00 00 00 42 00 6F 00 62 00 00 00

--length-- B o b EOS

  注意字符串的长度是如何被加到字符串数据中的。长度是DWORD类型的,保存了字符串中包含的字节数,但不包括结束标记。在这个例子中,"Bob"包含3个Unicode字符(不包括结束符),总共6个字节。字符串的长度被预先存储好,以便当一个BSTR在进程或者计算机之间被传递时,COM库知道多少数据需要传送。(另一方面,一个BSTR能够存储任意数据块,而不仅仅是字符,它还可以包含嵌入在数据中的0字符。)。

  在 C++ 中,一个 BSTR 实际上就是一个指向Unicode字符串中第一个字符的指针。它的定义如下:

BSTR bstr = NULL;

bstr = SysAllocString ( L"Hi Bob!" );

if ( NULL == bstr )

// out of memory error

// Use bstr here...

SysFreeString ( bstr );

  另外一个用在自动化接口中的变量类型是VARIANT。它被用来在无类型(typeless)语言,如Jscript和VBScript,来传递数据。一个VARIANT可能含有很多不同类型的数据,例如long和IDispatch*。当一个VARIANT包含一个字符串,字符串被存成一个BSTR。后面讲到VARIANT封装类时,会对VARIANT多些介绍。

2.2. BSTR的包装类_bstr_t

  _bstr_t是一个对BSTR的完整封装类,实际上它隐藏了底层的BSTR。它提供各种构造函数和操作符来访问底层的C语言风格的字符串。然而,_bstr_t却没有访问BSTR本身的操作符,所以一个_bstr_t类型的字符串不能被作为输出参数传给一个COM方法。如果你需要一个BSTR*参数,使用ATL类CComBSTR是比较容易的方式。

  一个_bstr_t字符串能够传给一个接收参数类型为BSTR的函数,只是因为下列3个条件同时满足。首先,_bstr_t有一个向wchar_t*转换的转换函数;其次,对编译器而言,因为BSTR的定义,wchar_t*和BSTR有同样的含义;第三,_bstr_t内部含有的wchar_t*指向一片按BSTR的形式存储数据的内存。所以,即使没有文档说明,_bstr_t可以转换成BSTR,这种转换仍然可以正常进行。

// Constructing

void Test_bstr_t()

{

_bstr_t bs1 = "char string"; // construct from a LPCSTR

_bstr_t bs2 = L"wide char string"; // construct from a LPCWSTR

_bstr_t bs3 = bs1; // copy from another _bstr_t

_variant_t v = "Bob";

_bstr_t bs4 = v; // construct from a _variant_t that has a string

// Extracting data

LPCSTR psz1 = bs1; // automatically converts to MBCS string

LPCSTR psz2 = (LPCSTR) bs1; // cast OK, same as previous line

LPCWSTR pwsz1 = bs1; // returns the internal Unicode string

LPCWSTR pwsz2 = (LPCWSTR) bs1; // cast OK, same as previous line

BSTR bstr = bs1.copy(); // copies bs1, returns it as a BSTR

// ...

SysFreeString ( bstr );

}

  注意_bstr_t也提供char*和wchar_t*之间的转换操作符。但不提倡使用,因为即使它们是非常量字符串指针,你也一定不能使用这些指针去修改它们指向的缓冲区的内容,因为那将破坏内部的BSTR结构。

2.3. _variant_t

  _variant_t是一个对VARIANT的完整封装,它提供很多构造函数和转换函数来操作一个VARIANT可能包含的大量的数据类型。这里,介绍与字符串有关的操作。

void TestVariant()

{

_variant_t v1 = "char string"; // construct from a LPCSTR

_variant_t v2 = L"wide char string"; // construct from a LPCWSTR

_bstr_t bs1 = "Bob";

_variant_t v3 = bs1; // copy from a _bstr_t object

// Extracting data

_bstr_t bs2 = v1; // extract BSTR from the VARIANT

_bstr_t bs3 = (_bstr_t) v1; // cast OK, same as previous line

}

注意:

  如果类型转换不能被执行,_variant_t方法能够抛出异常,所以应该准备捕获_com_error异常。

还需要注意的是:

  没有从一个_variant_t变量到一个MBCS

首页 上一页 2 3 4 5 下一页 尾页 5/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇查看当前系统可用的动态内存(C) 下一篇c语言中输入输出格式集合

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: