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 协议 ,转载请注明出处!