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 | A four-byte integer that contains the number of bytes in the following data string. It appears immediately before the first character of the data string. This value does not include the terminator. |
Data string | A string of Unicode characters. May contain multiple embedded null characters. |
Terminator | A 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;
}