2009-12-01 10 views
8

Tengo una variante bstr que se extrajo de MSXML DOM, por lo que está en UTF-16. Estoy tratando de averiguar lo que ocurre con la codificación por defecto esta conversión:Codificación predeterminada para la variante bstr a std :: cadena de conversión

VARIANT vtNodeValue; 
pNode->get_nodeValue(&vtNodeValue); 
string strValue = (char*)_bstr_t(vtNodeValue); 

De las pruebas, creo que la codificación predeterminada es Windows-1252 o ASCII, pero no estoy seguro.

Btw, este es el bloque de código que estoy arreglando y convirtiendo la variante en un wstring y yendo a una codificación de varios bytes con una llamada a WideCharToMultiByte.

Gracias!

Respuesta

10

El método operator char* llama al _com_util::ConvertBSTRToString(). The documentation es bastante inútil, pero supongo que usa la configuración regional actual para realizar la conversión.

Actualización:

Internamente, _com_util::ConvertBSTRToString() llamadas WideCharToMultiByte, que pasan a cero para todos los parámetros de la página de códigos y caracteres por defecto. Esto es lo mismo que pasar CP_ACP, lo que significa utilizar la configuración actual de la página de códigos ANSI del sistema (no la configuración actual de la secuencia).

Si desea evitar la pérdida de datos, probablemente debería llamar directamente al WideCharToMultiByte y usar CP_UTF8. Todavía puede tratar la cadena como una cadena de un solo byte terminada en nulo y usar std::string, simplemente no puede tratar los bytes como caracteres.

+2

¡Gracias! La página de códigos predeterminada en Windows de EE. UU. Es 1252, lo que es coherente con lo que he observado. Esto se puede determinar en cualquier máquina con esta llamada: \t int nCodePage = GetACP(); –

0

std::string por sí mismo no especifica/contiene ninguna codificación. Es meramente una secuencia de bytes. Lo mismo vale para std::wstring, que es simplemente una secuencia de wchar_t s (palabras de doble byte, en Win32).

Al convertir _bstr_t en un char* a través de su operator char*, simplemente obtendrá un puntero a los datos brutos. According to MSDN, estos datos consisten en caracteres anchos, es decir, wchar_t s, que representan UTF-16.

Me sorprende que realmente funcione para construir un std::string a partir de esto; no debería pasar el primer byte cero (que ocurre pronto, si su cadena original es inglés).

Pero desde wstring es una cadena de wchar_t, usted debe ser capaz de construir una directamente de la _bstr_t, de la siguiente manera:

_bstr_t tmp(vtNodeValue); 
wstring strValue((wchar_t*)tmp, tmp.length()); 

(no estoy seguro sobre length; es decir que el número de bytes o el número de caracteres?) Luego, tendrá un wstring codificado en UTF-16 al que puede llamar al WideCharToMultiByte.

+0

Eso no está bien, no es realmente un molde, 'bstr_t' tiene un' operador char * 'definido que hace la conversión internamente. –

+0

Lo sé. ¿Es inapropiada la palabra "emitir"? Quizás el "operador de conversión" sea mejor. Lo cambiaré. – Thomas

+0

Eso es incorrecto: al convertir un '_bstr_t' en' char * 'llama a la función' _com_util :: ConvertBSTRToString' para convertir la cadena en una codificación basada en bytes. – interjay

Cuestiones relacionadas