Как использовать FormatMessage Windows без неконтролируемого актера?C++

Программы на C++. Форум разработчиков
Ответить
Гость
 Как использовать FormatMessage Windows без неконтролируемого актера?

Сообщение Гость »

  • Вот довольно актуальный фрагмент кода, демонстрирующий, как загрузить сообщение об ошибке для кода ошибки Windows API. < /li>
    Вот много Старый фрагмент кода с использованием того же синтаксиса, чтобы сделать то же самое. или LPSTR и LPCSTR Обмен тем же представлением символов. br />
    Примечание особенно: < /li>
    < /ul>

    Код: Выделить всё

    [out] lpBuffer

    Указатель на буфер , который получает нулевую строку, которая указывает форматированное сообщение. Если dwflags включает в себя format_message_allocate_buffer , функция выделяет буфер с использованием функции Localalloc , и помещает указатель на буфер по адресу, указанному в lpbuffer . class = "lang-cpp prettyprint-override">

    Код: Выделить всё

    void ErrorExit()
    {
    LPVOID lpMsgBuf;
    DWORD dw = GetLastError();
    
    if (FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_FROM_SYSTEM |
    FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL,
    dw,
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    (LPTSTR) &lpMsgBuf,
    0, NULL) == 0) {
    MessageBox(NULL, TEXT("FormatMessage failed"), TEXT("Error"), MB_OK);
    ExitProcess(dw);
    }
    
    MessageBox(NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK);
    
    LocalFree(lpMsgBuf);
    ExitProcess(dw);
    }
    < /code>
    На моей настройке - X64, Visual Studio 2022 (V143), Windows 10 SDK - эти типы оцениваются следующим образом: < /p>
    
    < li>LPVOID
    : void *
  • formatmessage:

Код: Выделить всё

unsigned long FormatMessageW(
unsigned long dwFlags,
const void * lpSource,
unsigned long dwMessageId,
unsigned long dwLanguageId,
wchar_t * lpBuffer,
unsigned long nSize,
char ** Arguments
)
Как вы можете видеть, , что мы передаем , действительно «указатель на буфер»: void ** . Но то, что мы его подготовили в -просто буфер: wchar_t *.
И мы должны, как Formatmessage /-a /-W не принимает a ** (или *& ). Собираясь по своей подписи, он должен выделить буфер прямо at & lpmsgbuf , напишите второй wchar at (& lpmsgbuf) + sizeof (wchar_t) и в основном разбил наш стек. < Br /> (это не то, что происходит, конечно: оба связанных фрагментов кода работают как предполагалось, если не так, как ожидалось). < /p>
Мне кажется, что я должен обмануть Компилятор, позволяющий мне передать неправильный тип в функцию. > (например, я бы ожидал, что код - после расширения макроса - чтобы выглядеть так: < /p>

Код: Выделить всё

wchar_t * lpMsgBuf;
[...]
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
&lpMsgBuf,
0, NULL) == 0) {
[...]
Но это, конечно, не компилируется, как & lpmsgbuf wchar_t ** , а не wchar_t *.)
x /y Ответ: Оказалось, что современная < /em>, UTF-8 версия этого проклятого API вокруг?

Этот материал прямо из Microsoft «Let's Code максимально инопланетяне». К сожалению, getlasterror и оттуда Formatmessage , кажется, является единственным способом обработки ошибок для вызовов Windows API, таких как GetProcessaffinityMask, для которого в настоящее время не существует стандартного эквивалента C ++. Я бы предпочел не трогать это с помощью общеизвестного десятифутного шеста.

Подробнее здесь: https://stackoverflow.com/questions/794 ... ecked-cast
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»