请问C++中的BSTR和COM中的BSTR是一回事吗?

clxye 2010-07-16 08:32:41
以下内容该如何理解:

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 实际上就是一个指向字符串中第一个字符的指针。它的定义如下:

BSTR bstr = NULL;
bstr = SysAllocString ( L"Hi Bob!" );
if ( NULL == bstr )
// out of memory error
// Use bstr here...
SysFreeString ( bstr );
自然的,各种各样的BSTR封装类为你实现内存管理。

我看过COM相关的书,上面关于BSTR的确如文中所说,我也看过C++中的BSTR,它的确就是OLECHAR*类型,但感觉这完全就是两种不同的类型啊,不知道他所表达的意思是不是说在COM和C++中,BSTR表示的是不同的类型?

谢谢!!
...全文
415 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
clxye 2010-08-03
  • 打赏
  • 举报
回复
谢谢各位,特别是quicmous,讲得比较透彻!
klopow 2010-07-31
  • 打赏
  • 举报
回复
BSTR的原始定义在wtypes.idl中

typedef WCHAR OLECHAR;

typedef struct _FLAGGED_WORD_BLOB {
unsigned long fFlags;
unsigned long clSize;
[size_is(clSize)] unsigned short asData[];
} FLAGGED_WORD_BLOB;

typedef [unique] FLAGGED_WORD_BLOB *wireBSTR;
typedef [wire_marshal(wireBSTR)] OLECHAR *BSTR;


可见BSTR是使用FLAGGED_WORD_BLOB作列集格式的OLECHAR指针

wtypes.idl被midl编译后产生的wtypes.h中有

typedef OLECHAR *BSTR;

这个BSTR定义是给c/c++程序用的。如果midl能编译出wtypes.java,BSTR的java定义又是另一回事了。
原始BSTR指向FLAGGED_WORD_BLOB;M$用SysAllocString等API封装了列集过程,为了使用方便,还把BSTR调整指向asData[]。
向立天 2010-07-31
  • 打赏
  • 举报
回复
应该一样吧
jameshooo 2010-07-31
  • 打赏
  • 举报
回复
除了内存分配和释放必须使用特定API,使用上是没有区别的,从C/C++语言的角度来看,BSTR不是一种类型,只能用OLECHAR*代替
许野平 2010-07-31
  • 打赏
  • 举报
回复
一、BSTR 的内存格式

  存储一个长度为 n 的Unicode字符串,BSTR 需要 4 + 2n + 2 个字节的内存。其中前四个字节保存BSTR的字节长度,即 2n;然后中间 2n 个字节保存字符串内容;最后两个字节填充 0,用作字符串的结尾。

二、VC++ 对 BSTR 的特别处理

  在 VC++ 中,BSTR 就是一个指向 WCHAR 的指针。可是如果你认为这个指针直接指向了BSTR的最开始的地址,那就大错特错了。我们看下面这段代码:

BSTR bs;
OLECHAR *s = L"ABCDEFG";
bs = SysAllocString(s);

  查看 *((int*)bs-1) 或者 *((char*)bs-4)的值,可以看到结果是 14,也就是字符串的长度。呵呵,原来,bs实际上指向BSTR的第一个字符所在的位置,在这个指针前面,隐藏着4个字节的长度信息。

  VC++这样处理,使得 BSTR 与 LPOLECHAR 完全兼容——凡是需要LPOLECHAR的地方,都可以直接用BSTR变量替换。

  但是,反过来就不行了。绝对不要用 LPOLECHAR 变量去替换 BSTR 变量,因为 LPOLECHAR 前面没有隐藏 4 个字节的字符串长度信息。

三、在 COM 接口中使用 BSTR 变量

在 COM 接口中可能会有如下形式的函数:

void GetStr(BSTR * pVal)
{
pVal = ::SysAllocString(m_Str);
}

  记住,我们要用 SysAllocString 为输出参数分配内存。

  如何释放内存?你别担心,那是调用者的任务。调用者必须用 SysFreeString 释放你为他分配的内存。

  调用者可能使用完全不同的开发工具,他如何支持 SysFreeString?原因是,这两个函数是操作系统专门为 COM 组件提供的,跨越开发平台没有任何问题。



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/quicmous/archive/2010/07/31/5778301.aspx
  • 打赏
  • 举报
回复
他们就是一回事.
clxye 2010-07-16
  • 打赏
  • 举报
回复
高手们现个身啊...
rubyhlp0925 2010-07-16
  • 打赏
  • 举报
回复
一样的
tubo_true 2010-07-16
  • 打赏
  • 举报
回复
C++中的BSTR和
COM中的BSTR

我记得COM中有个CcomBstr
stonewater 2010-07-16
  • 打赏
  • 举报
回复
应该是同一个意思
clxye 2010-07-16
  • 打赏
  • 举报
回复
up一下

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧