3

BSTR这种奇怪的 Windows 数据类型是否具有一些特定用途,例如 COM 函数。根据 MSDN,它包含一个WCHAR字符串和一些其他内容,例如长度描述符。Windows 也很好地为我们提供了封装的_bstr_t BSTR;它负责分配和解除分配,并为您提供一些额外的功能。它有四个构造函数,包括一个接受 achar*和一个接受a 的构造函数wchar_t*。MSDN对前者的描述: “通过调用来构造一个对象,创建一个新对象,然后封装它。这个构造函数首先进行多字节到Unicode的转换。”_bstr_tSysAllocStringBSTR

它还具有可以提取指向字符串的指针的运算符,如、 和中的任何一个char*,我很确定这些都是以空值结尾的,这很酷。const char*wchar_t*

我花了一些时间阅读如何在多字节和 Unicode 之间进行转换,并且我已经看到很多关于如何使用mbstowcs和的讨论,以及由于编码可能不同,以及wcstomb如何更好,等等等等。这一切似乎都让人头疼,所以我想知道我是否可以构造 a并使用操作来访问字符串,这将是......更少的代码行:MultiByteToWideCharWideCharToMultiByte_bstr_t

char* multi = "asdf";
_bstr_t bs = _bstr_t(mb);
wchar_t* wide = (wchar_t*)bs; // assume read-only

我想我对此的直观回答是我们不知道 Windows 在幕后做什么,所以如果我在使用mbstowcs/时遇到问题wcstomb(我想我的意思是mbstowcs_s/ wcstomb_s)而不是MultiByteToWideChar/ WideCharToMultiByte,我不应该冒险,因为它是Windows 可能使用这些。(几乎可以肯定不会使用后者,因为我没有在此处指定“代码页”,不管是什么。)老实说,我还不确定我是否认为mbstowcs_sandwcstomb_s功能可以满足我的目的,因为我不确实掌握了所有不同的编码和东西,但这是一个完全不同的问题,它似乎在整个互联网上都得到了解决。

Sooooo,除了潜在的担忧之外,这样做有什么问题吗?

4

1 回答 1

2

在生产代码中使用_bstr_t::_bstr_t(const char*)并不是一个好主意:

_bstr_t通过调用SysAllocString创建一个新BSTR对象并封装它来构造一个对象。此构造函数首先执行多字节到 Unicode 的转换。如果s2太大,您[原文如此]可能会产生堆栈溢出错误。在这种情况下,请将您的转换char*wchar_twith MultiByteToWideChar,然后调用wchar_t *构造函数。

除此之外,这_bstr_t::operator wchar_t*() const throw()似乎几乎没有用。它仅用于结构成员提取,因此您被限制为const

这些运算符可用于提取指向封装的 Unicode 或多字节 BSTR 对象的原始指针。运算符将指针返回到实际的内部缓冲区,因此无法修改生成的字符串。

所以_bstr_t只是一个用于封装BSTRs 的辅助对象,而且是一个平庸的对象。使用MultiByteToWideCharand进行转换WideCharToMultiByte是一个更好的选择,原因有很多:

  • 它更不容易崩溃。
  • 您不会得到const缓冲作为回报,因为您提供了自己的缓冲。
  • 这些函数的名称是自描述的。通过不相关类型的构造函数和强制转换运算符进行转换不是。
于 2013-01-14T22:44:47.267 回答