繁体   English   中英

哪个是在C / C ++中将BSTR参数转换为ANSI的更好代码?

[英]Which is better code for converting BSTR parameters to ANSI in C/C++?

到目前为止,我发现我可以用两种(多种?)方式将传入的BSTR转换为ANSI,我很想知道在速度/效率等方面是否比另一种“更好”。

我一直使用的方式是使用USES_CONVERSIONW2A宏,例如

BSTR __stdcall F(BSTR p1, BSTR p2 ) {
    USES_CONVERSION;

    LPSTR sNum1 = W2A( p1 );
    LPSTR sNum2 = W2A( p2 );

然而,最近我遇到了另一种技术:

BSTR __stdcall F(BSTR p1, BSTR p2 ) {
    long amt = wcstombs( NULL, p1, 1 );
    sNum1 = (char *) malloc( amt ); 
    wcstombs( sNum1, p1, amt );
    *(sNum1 + amt) = '\0';

    amt = wcstombs( NULL, p2, 1 );
    sNum2 = (char *) malloc( amt ); 
    wcstombs( sNum2, p2, amt );
    *(sNum2 + amt) = '\0';

现在我授予你,它更啰嗦,并且有两次调用wcstombs但据我所知, USES_CONVERSIONW2A宏可能隐藏了各种各样的乐趣和游戏。

哪个代码更有效/更快? 或者,是否有另一种我可以使用的技术可以更好地完成工作?

来自MSDN

[...]建议的BSTR字符串转换方法是使用CComBSTR类。 要转换为BSTR,请将现有字符串传递给CComBSTR的构造函数。 要从BSTR转换,请使用COLE2 [C] DestinationType [EX],例如COLE2T。

从CComBSTR页面:

[...] CComBSTR类提供了许多成员(构造函数,赋值运算符和比较运算符),它们将ANSI或Unicode字符串作为参数。 这些函数的ANSI版本效率低于它们的Unicode版本,因为临时Unicode字符串通常是在内部创建的。 为提高效率,请尽可能使用Unicode版本。

在Nick的批准答案中注意,虽然正确分享了与描述​​宏的MSDN文档相同的问题。

问题是某些宏(如@Nick - COLE2A列出的宏)实际上并不存在。

然而,在MSDN页面的下方有一些文字可以让您了解这一事实,并使您能够找出正确的宏!

该文本列于下表中的表格中:

旧字符串转换宏与新字符串转换类之间存在几个重要差异:

在“新建ATL 7.0转换类”列中。

哪个说:

OLE总是等同于W.

所以@ Nick的例子中的宏实际上是CW2A

注意:

如果您使用ATL宏,例如:COLE2 [C] DestinationType [Ex](您可能应该这样做),请务必尽可能使用'C'版本,而不是您编写的非const版本。 对于显式BSTR-> ASCII转换(即:COLE2A),它们可能是等效的,但对于不需要实际转换的转换(例如:编译UNICODE时的COLE2T),'C'版本可以扩展为noops,而非如果源字符串是const,则-'C'版本仍将复制(因为您表示需要将结果字符串设置为非const)。

还要注意:

新的ATL7宏并不总是需要USES_CONVERSION,但是它们分配临时的r值对象,而旧的宏使用_alloca。 这可能重要,也可能不重要,具体取决于您的使用情况(例如,不要在循环中使用旧的宏运行很多次,你可以吹掉堆栈这样做)。

我用COM或BSTR做了很长时间,但我的建议是停止将BSTR视为一种特殊的东西。 将它们视为指向宽字符零终止字符串的指针...如果这样做可能更容易将它们转换为ANSI。 检查Eric的BSTR语义完整指南 ......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM