tipos programas programación programacion principiantes para lenguaje ingenieros estructuras ejemplos datos comandos basicos c++ c string cstring bstr

programas - programación en c++ para ingenieros



¿Cuál es el mejor código para convertir los parámetros BSTR a ANSI en C/C++? (4)

Desde MSDN :

[...] La forma recomendada de convertir hacia y desde cadenas BSTR es usar la clase CComBSTR . Para convertir a un BSTR, pase la cadena existente al constructor de CComBSTR. Para convertir desde un BSTR, use COLE2 [C] DestinationType [EX], como COLE2T.

Desde la página CComBSTR:

[...] La clase CComBSTR proporciona una cantidad de miembros (constructores, operadores de asignación y operadores de comparación) que toman cadenas ANSI o Unicode como argumentos. Las versiones ANSI de estas funciones son menos eficientes que sus contrapartes Unicode porque las cadenas Unicode temporales a menudo se crean internamente. Para mayor eficiencia, use las versiones Unicode siempre que sea posible.

Hasta ahora he descubierto que puedo convertir las BSTR entrantes a ANSI de dos (¿muchas?) Formas, y tengo curiosidad por saber si una es "mejor" que la otra con respecto a la velocidad / eficiencia, etc.

La forma en que he estado usando por un tiempo es usar las macros USES_CONVERSION y USES_CONVERSION , por ejemplo

BSTR __stdcall F(BSTR p1, BSTR p2 ) { USES_CONVERSION; LPSTR sNum1 = W2A( p1 ); LPSTR sNum2 = W2A( p2 );

Recientemente, sin embargo, me encontré con otra técnica:

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

Ahora te concedo, es más prolijo, y tiene dos llamadas a wcstombs pero por lo que sé, las macros USES_CONVERSION y USES_CONVERSION pueden estar ocultando todo tipo de diversión y juegos.

¿Cuál es el código más eficiente / más rápido? O bien, ¿hay otra técnica que podría usar que haría el trabajo mejor?


Nota:

Si usa las macros ATL, p. Ej .: COLE2 [C] DestinationType [Ex] (que probablemente debería), asegúrese de usar las versiones ''C'' como sea posible, no las versiones no const como las ha escrito. Pueden ser equivalentes para conversiones BSTR-> ASCII explícitas (es decir: COLE2A), pero para las conversiones donde no se requiere una conversión real (p. Ej .: COLE2T al compilar para UNICODE), las versiones ''C'' pueden expandirse a noops, mientras que las no Las versiones ''C'' seguirán copiando si la cadena fuente es const (porque estás expresando que necesitas que la cadena resultante no sea const).

También de la nota:

Las nuevas macros ATL7 no siempre requieren USES_CONVERSION, sin embargo, asignan objetos r-value temporales, mientras que las macros antiguas usan _alloca. Esto puede o no ser importante, dependiendo de su uso (por ejemplo, NO use las macros antiguas en un bucle que se ejecuta una gran cantidad de veces, puede apagar la pila haciéndolo).


Ha pasado mucho tiempo desde que hice algo con COM o BSTR, pero mi sugerencia es dejar de tratar el BSTR como algo especial. Trátelos como un puntero a una cadena terminada en cero de caracteres anchos ... si lo hace, podría ser más fácil convertirlos a ANSI. consulte la Guía Completa de Eric sobre Semántica BSTR ...


Tenga en cuenta en la respuesta aprobada por Nick, que si bien es correcto comparte el mismo problema que existe con la documentación de MSDN que describe las macros.

El problema es que algunas de las macros como la enumerada por @Nick - COLE2A, en realidad no existen.

Sin embargo, más adelante en la página de MSDN hay texto que te muestra este hecho y te lleva a descubrir la macro correcta.

El texto aparece en la tabla debajo del siguiente texto:

Existen varias diferencias importantes entre las macros de conversión de cadenas anteriores y las nuevas clases de conversión de cadenas:

En la columna Clases de conversión de New ATL 7.0.

Que dice:

OLE siempre es equivalente a W

Entonces, la macro en el ejemplo de @ Nick es realmente CW2A