Запретить препроцессору C выполнять определенную макроподстановку

Как я могу сказать препроцессору не заменять конкретный макрос?

Конкретная проблема заключается в следующем: файлы заголовков Windows определяют макрос GetMessage.

Мои заголовочные файлы C++ с моим API имеют метод GetMessage. Я не хочу переименовывать свой метод. Но при использовании API в Windows, включая windows.h, мой вызов метода GetMessage заменяется на GetMessageA.


person Vincent Oberle    schedule 14.11.2008    source источник
comment
Просто выполнять #undef GetMessage нехорошо, так как код, использующий API, также использует Windows GetMessage.   -  person Vincent Oberle    schedule 15.11.2008
comment
Ах, еще один пример неразборчивого использования Windows SDK макросов, затирающих все без исключения пространства имен (и не только в функции пространства имен C++).   -  person Michael Burr    schedule 15.11.2008
comment
@vincent: см. комментарий don.newfeld в ответе ShoeLace #undef GetMessage   -  person Michael Burr    schedule 15.11.2008


Ответы (5)


Вы пытались просто сделать

#undef GetMessage

или даже

#ifdef GetMessage
#undef GetMessage
#endif

а затем вызов окон GetMessageA или GetMessageW напрямую, в зависимости от того, что подходит.

вы должны знать, используете ли вы char* для wchar_t8..

(спасибо дон. Нойфельд)

Брайан также говорит, что, если добавить немного полезной информации, вы также можете использовать #pragma push_macro/pop_macro для отправки и извлечения определений макросов. Это замечательно, если вы хотите переопределить определение макроса в блоке кода:

#pragma push_macro("GetMessage")
#undef GetMessage

// Your GetMessage usage/definition here

#pragma pop_macro("GetMessage")

Я подозреваю, что это особенность MS, так что имейте это в виду.

person ShoeLace    schedule 14.11.2008
comment
Но тогда я больше не могу использовать Windows GetMessage - person Vincent Oberle; 15.11.2008
comment
Да, вы можете, просто вызовите GetMessageA или GetMessageW напрямую, в зависимости от того, что подходит. - person Don Neufeld; 15.11.2008
comment
И да, push_macro и pop_macro специфичны для MS. Прагмы определяются реализацией по определению, и я не заметил их вне кода MS. Конечно, это может не быть проблемой для тех, кто кодирует Windows API. - person David Thornley; 26.01.2009
comment
#pragma push_macro и #pragma pop_macro поддерживаются, начиная с gcc 4.3. - person Naszta; 09.09.2013

(GetMessage)(...)

GetMessage в MSDN

person MSN    schedule 14.11.2008
comment
Хотя это часто является хорошим способом избежать непреднамеренного уничтожения макросом, я не думаю, что это сработает для GetMessage, поскольку он не определен как «подобный функции» макрос. - person Michael Burr; 15.11.2008
comment
Ах да... это работает только в том случае, если функция объявлена ​​перед макросом, а не после (что, я думаю, в любом случае не гарантируется). MSN - person MSN; 21.11.2008

Немного полезной информации: вы также можете использовать #pragma push_macro/pop_macro для отправки и извлечения определений макросов. Это замечательно, если вы хотите переопределить определение макроса в блоке кода:

#pragma push_macro("GetMessage")
#undef GetMessage

// Your GetMessage usage/definition here

#pragma pop_macro("GetMessage")

Я подозреваю, что это особенность MS, так что имейте это в виду.

person Brian    schedule 14.11.2008
comment
Специфика MS не должна быть проблемой, так как проблема заключается в макросе, определенном в windows.h :-P - person Evan Teran; 15.11.2008
comment
Это проблема, потому что существуют наборы компиляторов, отличных от MS, предназначенные для Windows (например, mingw). - person CesarB; 15.11.2008

Есть ли код, который вызывает как ваш GetMessage, так и GetMessage Window?

Такой код не сможет различать их. Вы не сможете вызывать оба в одном файле.

Если вы используете одну функцию в одном файле, а другую в другом, просто выполните предложенный #undef в одном файле.

person David Norman    schedule 14.11.2008

Учитывая ваши ограничения, изложенные в вашем комментарии, единственный способ сделать это - сделать:

#undef GetMessage

прямо перед вызовом GetMessage вашего API. (И это предполагает, что никто после этой точки в исходном файле не вызывает Win32 GetMessage.)

person Jim Buck    schedule 14.11.2008
comment
Это не единственный способ, но он потребует, чтобы вы НЕ включали windows.h. :) - person OJ.; 15.11.2008