一、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 组件提供的,跨越开发平台没有任何问题。