C++ BSTR数据类型

BSTR(Basic string or binary string)是COM 、Automatic、Interop 使用的string数据类型。在从脚本访问的所有接口中使用BSTR。

typedef WCHAR OLECHAR;
typedef OLECHAR* BSTR;
typedef BSTR* LPBSTR;

BSTR是一个复合性的数据类型,其包含长度前缀(length prefix),字符串数据(Data string),和结尾标志(Terminator)。

Item Description
Length prefix 一个四字节整数,包含以下数据字符串中的字节数。它出现在数据字符串的第一个字符之前。该值不包括终止符。
Data string 一串 Unicode 字符。可能包含多个嵌入的空字符。
Terminator NULL (0x0000) WCHAR。

长度前缀:4字节的整数,描述字符串数据的长度。出现在字符串数据的第一个字符之前。

字符串数据:Unicode编码的字符串,可包含多个嵌入的空字符。

结尾标志:空的WCHAR

一个BSTR是一个指针,其指向string数据的第一个字符,而非长度前缀。

BSTR由COM内存分配函数分配,所以能被函数直接返回,不用考虑内存的分配问题。

以下的声明方式是不对的。

BSTR MyBstr = L"I am a happy BSTR";

这么写的话编译和链接是正确的,但这种写法是错误的。因为BSTR是复合类型,其开头前缀是描述字符串长度的,中间才是真正的数据内容,结尾还有结尾标志。

正确的声明方式是这样的:

BSTR MyBstr = SysAllocString(L"I am a happy BSTR");

编译器会检查它的内存地址,在其前面加上长度前缀和结尾标志,因为该字符串前加了‘L’,表示是Unicode编码,所以长度为34。

同理,以下的转换方式是错误的。

BSTR myBstr2=(BSTR)L"I am a happy BSTR";

正确的转换方式是这样的:

BSTR myBstr2=_com_util::ConvertStringToBSTR(L"I am a happy BSTR");

BSTR和char* 的转换:

char* ->BSTR:

// ConvertStringToBSTR.cpp
#include <comutil.h>
#include <stdio.h>
 
#pragma comment(lib, "comsuppw.lib")
#pragma comment(lib, "kernel32.lib")
 
int main() {
   char* lpszText = "Test";
   printf_s("char * text: %s\n", lpszText);
 
   BSTR bstrText = _com_util::ConvertStringToBSTR(lpszText);
   wprintf_s(L"BSTR text: %s\n", bstrText);
 
   SysFreeString(bstrText);
}

BSTR->char*

// ConvertBSTRToString.cpp
#include <comutil.h>
#include <stdio.h>
 
#pragma comment(lib, "comsuppw.lib")
 
int main() {
   BSTR bstrText = ::SysAllocString(L"Test");
   wprintf_s(L"BSTR text: %s\n", bstrText);
 
   char* lpszText2 = _com_util::ConvertBSTRToString(bstrText);
   printf_s("char * text: %s\n", lpszText2);
 
   SysFreeString(bstrText);
   delete[] lpszText2;
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!