2009-12-01 14 views
8

Ho una variante bstr che è stata estratta dal DOM MSXML, quindi è in UTF-16. Sto cercando di capire che cosa codifica di default si verifica con questa conversione:Codifica predefinita per la variante da bstr a std :: conversione stringa

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

Da test, credo che la codifica di default è o di Windows-1252 o ASCII, ma non sono sicuro.

Btw, questo è il blocco di codice che sto correggendo e convertendo la variante in wstring e andando a una codifica multi-byte con una chiamata a WideCharToMultiByte.

Grazie!

risposta

10

Il metodo operator char* chiama _com_util::ConvertBSTRToString(). The documentation è piuttosto inutile, ma presumo che usi le impostazioni locali correnti per fare la conversione.

Aggiornamento:

Internamente, _com_util::ConvertBSTRToString() chiamate WideCharToMultiByte, passando zero per tutti i parametri code-page e carattere di default. È lo stesso di passare CP_ACP, che significa utilizzare l'impostazione corrente della pagina di codice ANSI del sistema (non l'impostazione corrente del thread).

Se si desidera evitare di perdere dati, è consigliabile chiamare direttamente lo WideCharToMultiByte e utilizzare CP_UTF8. È ancora possibile trattare la stringa come una stringa a singolo byte con terminazione null e utilizzare std::string, non è possibile trattare byte come caratteri.

+2

Grazie !!! La pagina di codice predefinita su Windows USA è 1252, che è coerente con ciò che ho osservato. Questo può essere determinato su qualsiasi macchina con questa chiamata: \t int nCodePage = GetACP(); –

0

std::string da solo non specifica/contiene alcuna codifica. È semplicemente una sequenza di byte. Lo stesso vale per std::wstring, che è semplicemente una sequenza di wchar_t s (parole a doppio byte, su Win32).

Convertendo _bstr_t in un char* tramite il suo operator char*, otterrete semplicemente un puntatore ai dati grezzi. According to MSDN, questi dati sono composti da caratteri ampi, ovvero wchar_t s, che rappresentano UTF-16.

Sono sorpreso che funzioni effettivamente per costruire un std::string da questo; non dovresti superare il primo byte zero (che si verifica presto, se la tua stringa originale è l'inglese).

Ma poiché wstring è una stringa di wchar_t, si dovrebbe essere in grado di costruire uno direttamente dalla _bstr_t, come segue:

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

(io non sono sicuro di length, è esso il numero di byte o il numero di caratteri?) Quindi, avrai un wstring codificato in UTF-16 sul quale puoi chiamare WideCharToMultiByte.

+0

Non è giusto, non è davvero un cast, 'bstr_t' ha un' operatore char * 'definito che esegue la conversione internamente. –

+0

Lo so. La parola "cast" è inappropriata? Forse "l'operatore di conversione" è migliore. Lo cambierò. – Thomas

+0

Che non è corretto: lanciare un '_bstr_t' a' char * 'chiama la funzione' _com_util :: ConvertBSTRToString' per convertire la stringa in una codifica basata su byte. – interjay