Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

So far I've discovered I can convert incoming BSTRs to ANSI in two (of many?) ways, and I'm curious to know whether one is "better" than the other with respect to speed / efficiency etc.

The way I've been using for a while is use the USES_CONVERSION and W2A macros, e.g.

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

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

Recently, however, I came across another technique:

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';

Now I grant you, it's wordier, and has two calls to wcstombs but for all I know the USES_CONVERSION and W2A macros may be hiding all sorts of fun and games.

Which is the more efficient / faster code? Or, is there another technique I could use that would do the job better?

like image 620
bugmagnet Avatar asked Dec 10 '22 21:12

bugmagnet


2 Answers

From MSDN:

[...]The recommended way of converting to and from BSTR strings is to use the CComBSTR class. To convert to a BSTR, pass the existing string to the constructor of CComBSTR. To convert from a BSTR, use COLE2[C]DestinationType[EX], such as COLE2T.

From the CComBSTR page:

[...]The CComBSTR class provides a number of members (constructors, assignment operators, and comparison operators) that take either ANSI or Unicode strings as arguments. The ANSI versions of these functions are less efficient than their Unicode counterparts because temporary Unicode strings are often created internally. For efficiency, use the Unicode versions where possible.

like image 86
dirkgently Avatar answered Jan 21 '23 01:01

dirkgently


Note in the approved answer by Nick, which whilst correct shares the same problem there is with the MSDN documentation that describes the macros.

The problem is that some of the macros such as the one listed by @Nick - COLE2A, don't actually exist.

However further down the MSDN page there is some text that clues you into this fact and leads you to be able to figure out the correct macro!

The text is listed in the table under the following text:

There are several important differences between the older string conversion macros and the new string conversion classes:

In the New ATL 7.0 Conversion Classes column.

Which says:

OLE is always equivalent to W

So the macro in @Nick's example is actually CW2A

like image 36
Peter Nimmo Avatar answered Jan 21 '23 01:01

Peter Nimmo