2009-12-01 17 views
8

Tôi có một biến thể bstr được lấy từ MSXML DOM, vì vậy nó nằm trong UTF-16. Tôi đang cố gắng tìm hiểu xem mã hóa mặc định nào xảy ra với chuyển đổi này:Mã hóa mặc định cho biến thể bstr thành std :: string conversion

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

Từ thử nghiệm, tôi tin rằng mã hóa mặc định là Windows-1252 hoặc Ascii nhưng không chắc chắn.

Btw, đây là đoạn mã mà tôi đang sửa và chuyển đổi biến thể thành chuỗi và chuyển sang mã hóa nhiều byte với lệnh gọi tới WideCharToMultiByte.

Cảm ơn!

Trả lời

10

Gọi phương thức operator char*_com_util::ConvertBSTRToString(). The documentation là khá vô ích, nhưng tôi cho rằng nó sử dụng cài đặt miền địa phương hiện tại để thực hiện chuyển đổi.

Cập nhật:

Bên trong, _com_util::ConvertBSTRToString() cuộc gọi WideCharToMultiByte, đi qua không cho tất cả các thông số mã trang và nhân vật mặc định. Điều này giống với việc truyền CP_ACP, có nghĩa là sử dụng cài đặt mã ANSI hiện tại của hệ thống (không phải cài đặt luồng hiện tại).

Nếu bạn muốn tránh mất dữ liệu, bạn có thể gọi trực tiếp WideCharToMultiByte và sử dụng CP_UTF8. Bạn vẫn có thể coi chuỗi là chuỗi byte một byte được kết thúc bằng null và sử dụng std::string, bạn không thể coi byte là ký tự.

+2

Cảm ơn !!! Trang mã mặc định trên US Windows là 1252, phù hợp với những gì tôi đã quan sát. Điều này có thể được xác định trên bất kỳ máy nào có cuộc gọi này: \t int nCodePage = GetACP(); –

0

std::string tự nó không chỉ định/chứa bất kỳ mã hóa nào. Nó chỉ đơn thuần là một chuỗi các byte. Điều tương tự giữ cho std::wstring, chỉ là một chuỗi gồm wchar_t s (các từ hai byte, trên Win32).

Bằng cách chuyển đổi _bstr_t thành char* thông qua operator char*, bạn sẽ chỉ nhận được con trỏ đến dữ liệu thô. According to MSDN, dữ liệu này bao gồm các ký tự rộng, nghĩa là, wchar_t s, đại diện cho UTF-16.

Tôi ngạc nhiên rằng nó thực sự hoạt động để xây dựng một số std::string từ điều này; bạn không nên vượt qua byte số 0 đầu tiên (xảy ra sớm, nếu chuỗi ban đầu của bạn là tiếng Anh).

Nhưng kể từ wstring là một chuỗi các wchar_t, bạn sẽ có thể xây dựng một trực tiếp từ _bstr_t, như sau:

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

(Tôi không chắc chắn về length; là nó số byte hoặc số ký tự?) Sau đó, bạn sẽ có một số wstring được mã hóa bằng UTF-16 mà bạn có thể gọi WideCharToMultiByte.

+0

Điều đó không đúng, nó không thực sự là một diễn viên, 'bstr_t' có một toán tử' char * 'được định nghĩa trong đó chuyển đổi nội bộ. –

+0

Tôi biết. Từ "đúc" có phù hợp không? Có lẽ "nhà điều hành chuyển đổi" là tốt hơn. Tôi sẽ thay đổi nó. – Thomas

+0

Điều đó không chính xác: việc tạo một '_bstr_t' thành' char * 'gọi hàm' _com_util :: ConvertBSTRToString' để chuyển đổi chuỗi thành mã hóa dựa trên byte. – interjay

Các vấn đề liên quan