Charset используется сообщением об ошибке boost-asio

Я использую boost-asio и хочу правильно обработать сообщение об ошибке.

В этом примере я сделал опечатку (1278 вместо 127):

boost::system::error_code ec;
auto address=boost::asio::ip::address::from_string("1278.0.0.1",ec);
if(ec)
{
    const char*text=ec.message().c_str();
    //Do Something with text but what is its encoding ?
}

Я получаю сообщение об ошибке, и оно, похоже, закодировано в Windows 1252 (я использую Windows 7). Так что похоже, что кодировка - это кодировка ОС.

Тем не менее, я не смог найти никаких документов, подтверждающих этот факт.

Кодируются ли сообщения об ошибках в boost asio с помощью набора символов ОС?

1 ответ

Решение

После анализа в моей системе boost я обнаружил, что включенные hpp-файлы включают в себя ipp-файл, который, в свою очередь, вызывает функции ОС. Если есть ошибка, на данном этапе известен только код ошибки.

Реальное сообщение об ошибке формируется при вызове функции message().

Реализация в окнах вызывает FormatMessageA или FormatMessageW в зависимости от того, определен ли BOOST_NO_ANSI_APIS:

  std::string system_error_category::message( int ev ) const
  {
# ifndef BOOST_NO_ANSI_APIS  
    LPVOID lpMsgBuf = 0;
    DWORD retval = ::FormatMessageA( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM | 
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        ev,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPSTR) &lpMsgBuf,
        0,
        NULL 
    );
    detail::local_free_on_destruction lfod(lpMsgBuf);
    if (retval == 0)
        return std::string("Unknown error");

    std::string str( static_cast<LPCSTR>(lpMsgBuf) );
# else  // WinCE workaround
    LPVOID lpMsgBuf = 0;
    DWORD retval = ::FormatMessageW( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM | 
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        ev,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPWSTR) &lpMsgBuf,
        0,
        NULL 
    );
    detail::local_free_on_destruction lfod(lpMsgBuf);
    if (retval == 0)
        return std::string("Unknown error");

    int num_chars = (wcslen( static_cast<LPCWSTR>(lpMsgBuf) ) + 1) * 2;
    LPSTR narrow_buffer = (LPSTR)_alloca( num_chars );
    if (::WideCharToMultiByte(CP_ACP, 0, static_cast<LPCWSTR>(lpMsgBuf), -1, narrow_buffer, num_chars, NULL, NULL) == 0)
        return std::string("Unknown error");

    std::string str( narrow_buffer );
# endif
    while ( str.size()
      && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
        str.erase( str.size()-1 );
    if ( str.size() && str[str.size()-1] == '.' ) 
      { str.erase( str.size()-1 ); }
    return str;
  }

Если сообщение вызывает FormatMessageW, строка сужается до системной кодовой страницы Windows ANSI по умолчанию (CP_ACP).

Во всех случаях в Windows результатом является кодовая страница ANSI по умолчанию.

Другие вопросы по тегам