Подтвердить что ты не робот

Любая утилита для тестирования расширяет макросы C/С++ #define?

Кажется, я часто трачу слишком много времени, пытаясь получить макроС#define, чтобы сделать именно то, что я хочу. Я напишу свою текущую дилемму ниже, и любая помощь будет оценена. Но действительно ли большой вопрос заключается в том, есть ли какая-нибудь полезность, которую кто-то может рекомендовать, чтобы быстро отобразить, что делает макрос? Похоже, что даже медленный процесс проб и ошибок будет намного быстрее, если я смогу понять, что не так.

В настоящее время я динамически загружаю длинный список функций из созданной мной DLL. То, как я это задал, указатели на функции имеют те же самые имена, что и экспортированные функции, а typedef (s), используемые для прототипа, имеют одинаковые имена, но с добавленным подчеркиванием. Поэтому я хочу использовать define для упрощения присваивания длинного длинного списка указателей функций.

Например, в приведенном ниже примере кода "hexdump" - это имя точки функции typedef'd, а также имя функции, а _hexdump - это имя typedef. Если GetProcAddress() терпит неудачу, счетчик сбоев увеличивается.

if (!(hexdump = (_hexdump)GetProcAddress(h, "hexdump"))) --iFail;

Итак, скажем, я хотел бы заменить каждую строку, как показано выше, макросом, как это...

GETADDR_FOR(hexdump )

Хорошо, это лучшее, что я придумал до сих пор. Это не работает (мой//комментарий только для предотвращения форматирования текста в сообщении)...

// #define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) --iFail; 

И снова, пока я бы оценил, какую глупую ошибку я сделал, это заставит мой день иметь утилиту, которая покажет мне ошибку моих способов, просто подключив мой макрос.

4b9b3361

Ответ 1

Вы можете просто запустить свой код через препроцессор, который покажет вам, что он будет расширен (или выплюнуть ошибки по мере необходимости):

$ cat a.c
#define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) 
GETADDR_FOR(hexdump)

$ gcc -E a.c
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.c"
a.c:1:36: error: '#' is not followed by a macro parameter

GETADDR_FOR(hexdump)

В GCC он gcc -E foo.c выполняет только предварительную обработку файла.

Visual Studio использует аргумент /P.

Ответ 3

Перейдите в https://godbolt.org/. Введите свой код в левую панель и выберите компилятор в качестве gcc, чтобы аргумент был равен -E в правой панели. Ваш предварительно обработанный код появится справа.

Ответ 4

Похоже, вы смущены тем, что точный синтаксис предназначен для подшивки или прикрепления токенов в макросах препроцессора C.

Вы можете найти эту страницу о макросах препроцессора C в целом.

В частности, я думаю, что этот макрос должен выглядеть следующим образом:

#define GETADDR_FOR(a) if (!(a = (_##a)GetProcAddress(h, #a))) --iFail

Конечный ; должен быть пропущен, потому что вы, вероятно, напечатаете его как GETADDR_FOR(hexdump);, и если вы этого не сделаете, это будет очень странно в вашем C-коде и смутить многие синтаксические выделения.

И как кто-то упомянул gcc -E, запустит препроцессор и пропустит другие шаги компиляции. Это полезно для отладки задач препроцессора.

Ответ 5

Возможно, вы захотите взглянуть на Boost Wave. Как и большинство Boost, это скорее библиотека, чем утилита, но у нее есть драйвер для работы в качестве препроцессора.