有没有办法写一个BSTR文字?

时间:2015-01-13 09:31:17

标签: c++ c++builder bstr

当调用一个期望BSTR的函数时,能够编写类似的东西很好:

iFoo->function( bs"HELLO" );

然而,我唯一知道的解决方法是使用调用SysAllocString等的包装器,例如:

iFoo->function( WideString(L"HELLO").c_bstr() );

这有点难看。实际上是否存在创建BSTR字面值的选项?

动机:通过避免分配和释放,更易于阅读的代码和更快的运行时性能。

澄清:我只讨论调用者(即我们)拥有BSTR所有权的情况,例如:调用带有BSTR [in]参数的函数。当然,向一个函数提供指向BSTR文字的指针是愚蠢的,这个函数将继续尝试释放字符串。

2 个答案:

答案 0 :(得分:4)

用户定义的文字将是最佳选择:

"HELLO"_bstr调用template<char...> BSTR operator "" _bstr ( const char*, std::size_t),然后可以调用SysAllocString()

VS14中的新功能。

[编辑]

根据评论,最好返回_bstr_t或其他获得SysAllocString()结果所有权的类,并隐式转换为BSTR。此临时值将在完整表达式结束时销毁,因此 iFoo->function( "HELLO"_bstr );之后的将返回。

答案 1 :(得分:3)

要跟进@ MSalters的回答,自定义用户定义的文字可能如下所示:

CComBSTR operator "" _bstr (const char* str, std::size_t len)
{
    return CComBSTR(len, str);
}

然后您可以执行此操作(因为CComBSTR已定义BSTR转化运算符):

iFoo->function( "HELLO"_bstr );

您甚至可以为多个输入字符串文字类型重载运算符:

CComBSTR operator "" _bstr (const wchar_t* str, std::size_t len)
{
    return CComBSTR(len, str);
}

CComBSTR operator "" _bstr (const char16_t* str, std::size_t len)
{
    return CComBSTR(len, (wchar_t*)str);
}

iFoo->function( L"HELLO"_bstr ); // calls wchar_t* version with UTF-16 encoded data

iFoo->function( u"HELLO"_bstr ); // calls char16_t* version with UTF-16 encoded data

iFoo->function( u8"HELLO"_bstr ); // calls char* version with UTF-8 encoded data...

请注意最后一种情况。由于运算符不知道它是传递ANSI还是UTF-8数据,并且CComBSTR在传递char*数据时假设ANSI,您应该使用不同的文字后缀来区分,以便您可以转换UTF -8正确,例如:

CComBSTR operator "" _utf8bstr (const char* str, std::size_t len)
{
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> conv;
    std::wstring wstr = conv.from_bytes(std::string(str, len));
    return CComBSTR(wstr.length(), wstr.c_str());
}

iFoo->function( u8"HELLO"_utf8bstr );