Ошибка при включении winuser.h.Он определяет ChangeMenu для ChangeMenuW или ChangeMenuA - PullRequest
0 голосов
/ 17 декабря 2018

Работа над приложением Qt в Windows.Я включаю QVboxLayout только в мой исходный файл, и это вызывает ошибки, потому что его макрос перезаписывает имя моего метода.

foo.hpp
class foo
{
    ChangeMenu();
}

foo.cpp
#include "foo.hpp"
#include "QVBoxLayout" // <--- this includes winuser.h

foo::ChangeMenu(){};

Теперь, что происходит, так это то, что winuser.h имеет макрос

#ifdef UNICODE
#define ChangeMenu  ChangeMenuW
#else
#define ChangeMenu  ChangeMenuA
#endif // !UNICODE

Это меняетмое определение функции для ChangeMenuW, но мое объявление все еще ChangeMenu.

Как мне решить эту проблему?Как winuser.h может определить такое «нормальное» имя как макрос?

Версия winuser.h - это «windows kits \ 10 \ include \ 10.0.16299.0»

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Вы не могли бы позаботиться об этой проблеме, хотя имя вашего метода будет таким же, как в Windows API, но система не будет смешивать их (просто объедините Unicode в обоих местах для определения / вызова).Если вы позвоните ChangeMenu() напрямую, вы позвоните в winapi, а если

foo f;
f.ChangeMenu();

или

foo::ChangeMenu(); (статический)

, вы вызовете свой метод.

А если вы хотите отключить winapi:

#ifdef ChangeMenu
#undef ChangeMenu
    //code place that you define/call your own ChangeMenu().
#ifdef UNICODE
#define ChangeMenu  ChangeMenuW
#else
#define ChangeMenu  ChangeMenuA
#endif // !UNICODE
#endif

(выглядит очень утомительно.)

0 голосов
/ 18 декабря 2018

Практически любой Windows API, работающий со строками, на самом деле является макросом, который разрешается в A или W версии.Обходного пути нет, вы можете:

  • избегать включения windows.h, но, как вы заметили, он проползает;
  • жестоко #undef макрос перед определением / использованием вашегофункция;это подходящее наказание за накопление таких обычных и немарокодных идентификаторов, но это утомительно, и некоторый другой код может фактически нуждаться в функции Win32;
  • просто примите это как печальный факт жизни и избегайте всехсоответствующие имена Win32 API;если вы используете Qt и соблюдаете его соглашение об именах, это должно быть легко, поскольку функции Qt используют lowerCamelCase (в отличие от Win32 UpperCamelCase);
  • включает windows.h прямо в заголовке (возможно, под #ifdef _WIN32));это гарантирует, что ваш идентификатор будет заменен макросом во всех случаях, поэтому все будет работать нормально, даже если компилятор фактически скомпилирует функцию с другим именем;подходит для автономных проектов, не подходит для библиотек.(Спасибо @ Джонатану Поттеру за предложение)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...