BSTR详解一
COM 是一种跨编程语言的平台,需要提供语言无关的数据类型。多数编程语言有自己的字符串表示。 
- C++ 字符串是以 0 结束的 ASCII 或 Unicode 字符数组
- Visual Basic 字符串是一个 ASCII 字符数组加上表示长度的前缀。
- Java 字符串是以 0 结束的 Unicode 字符数组。
需要定义一种通用的字符串类型,可以很容易的匹配到不同编程语言。在 C++ 中,就是 BSTR 。 
2.1       BSTR 简介 
" Basic STRing " 的简称,微软在 COM/OLE 中定义的标准字符串数据类型。对于 C++ , Windows 头文件 wtypes.h 中定义如下: 
typedef wchar_t WCHAR; 
typedef WCHAR OLECHAR; 
typedef OLECHAR __RPC_FAR *BSTR;; 
2.2       BSTR 实现 
在 COM 中,字符用 16-bit OLECHAR 表示,这样使 COM 可以支持各种 code pages ,包括 Unicode 。对于 windows 系统,可以简单理解为 OLECHAR 使用的就是 Unicode 。 OLECHAR 串与单字节字符串很类似,是一个以 null 结尾的 buffer 。唯一的区别是每个字符占两个字节,而不是一个 
 0 1 2 3 4 5 6 7 8 9 0 1 
| H | E | L | L | O | \0| 
 ^ 
 OLCHAR 
Figure 1. Format of an OLECHAR string. 
使用以 Null 结尾的简单字符串在 COM component 间传递不太方便。因此,标准 BSTR 是一个有长度前缀和 null 结束符的 OLECHAR 数组。 BSTR 的前 4 字节是一个表示字符串长度的前缀。 BSTR 长度域的值是字符串的字节数,并且不包括 0 结束符。由于是 Unicode 串,所以字符数是字节数的一半。这种方式的优点是允许程序员在 BSTR 串中间嵌入 NULL 字符。但是, BSTR 的前四个字节表示长度,而 OLECHAR 数组的前四字节表示前两个字符。这种情况下,对于 C++ 程序,如何实现 BSTR 和 OLECHAR 的交换?答案是 COM 提供了两个 BSTR 分配用的 API : SysAllocString / SysReallocString 。函数返回的指针指向 BSTR 的第一个字符,而不是 BSTR 在内存的第一个字节。 
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 
0a000000 | H | E | L | L | O | \0| 
         ^ 
         BSTR 
下面是 SysAllocString 和 SysFreeString 的伪代码。 
BSTR SimpleSysAllocString( const OLECHAR * sz) 
{ 
    if ( sz == NULL) return NULL; 
    BYTE* buf = new BYTE[sizeof(INT32) + (wcslen(sz)+1)*sizeof(OLECHAR) ]; 
    if(buf == NULL) 
    { 
        return NULL; 
    } 
    else 
    { 
        INT32 len = wcslen(sz) * sizeof(OLECHAR); 
        *((INT32*) buf) = len; 
        wcscpy( (WCHAR*)(buf+sizeof(INT32)), sz); 
        return (BSTR)(buf+sizeof(INT32)); 
    } 
} 
VOID SimpleSysFreeString( BSTR bstr) 
{ 
    if(bstr != NULL) 
    { 
       BYTE* start = (BYTE*)bstr - sizeof(INT32); 
       delete []start; 
    } 
} 
  
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号