У нас есть старое приложение C ++, которое делает вызовы сторонним веб-сервисам, используя WinHttp.WinHttpRequest.5.1.
Я не буду перечислять все детали последовательности вызовов, так как я не думаю, что это имеет отношение к проблеме, но мы заканчиваем с вызовом hr = pIWinHttpRequest->get_ResponseText(&bstrResponse);
, где bstrResponse
имеет тип BSTR.
Вызывающий код не работает с BSTR, он работает со стандартным C / C ++ char *
с, поэтому код преобразует BSTR в char *
с:
_bstr_t b(bstrResponse);
const char *c = static_cast<char *>(b);
И для всех предыдущих веб-сервисов, к которым мы обращались с помощью этого кода, это сработало. Но для этого нового это не так.
Предполагается, что данные, которые мы возвращаем, должны быть XML, но для этого веб-сервиса, похоже, у нас возникают проблемы с преобразованием кода символов. Наша результирующая строка начинается с; "?<?xml version="1.0" encoding="utf-8"?>..."
Обратите внимание на дополнительные ?
в начале. Проходя через это в отладчике, мы не видим это в отображаемом значении bstrResponse
и мы не видим его в отображаемом значении b
, но мы видим это в отображаемом значении c
,
Любые идеи относительно того, что может происходить?
РЕДАКТИРОВАНИЕ
Я понимаю, что BSTR является многобайтовым типом, но все символы в этой строке являются простым ASCII, и ни один из кодов, вызывающих эту функцию, не может обрабатывать многобайтовые символы. Просматривая веб-сайты, я вижу, что этот конкретный механизм рекомендуется часто, но в этом случае он не работает.
Мне нужно преобразовать эту строку из BSTR в массив однобайтовых символов. Даже если это означает удаление многобайтовых символов, которые не могут быть преобразованы.
Конвертация в вашем коде с использованием static_cast
на _bstr_t
правильно конвертирует в ANSI. Появление ?
в преобразовании кодировки указывает, что преобразование символа не удалось. Наиболее вероятной причиной этого является то, что bstrResponse
содержит символы, которых нет в вашей кодовой странице ANSI. Я ожидаю, что вы должны переходить на UTF-8, а не ANSI, но, конечно, у меня нет всей информации, которая у вас есть.
Суть в том, что ?
указывает, что исходная строка содержит символ, который не может быть закодирован в наборе символов назначения.
Обновить
Ваш ответ еще раз подтверждает, что вы должны перейти на UTF-8. Только вы можете знать наверняка, но представленные вами доказательства согласуются с этим выводом.
Оказывается, было две проблемы. Во-первых, описанный выше процесс преобразования не удаляет метку порядка байтов, что, на мой взгляд, должно быть, а во-вторых, что старый синтаксический анализатор C ++ XML, который мы используем, блокирует 8-битные символы ASCII, и этот веб-сервис отправляет нам символ авторского права в их тексте, ASCII ‘\ xA9’.
С разделенной спецификацией и заменой высокобитовых символов пробелами парсер работает нормально.