Кажется, что я часто провожу слишком много времени, пытаясь заставить #define макрос делать точно, что я хочу. Я отправлю свою текущую дилемму ниже, и любая справка ценится. Но действительно больший вопрос состоит в том, существует ли какая-либо утилита, которую кто-то мог бы рекомендовать, для быстрого отображения то, что на самом деле делает макрос? Кажется, что даже медленный процесс метода проб и ошибок пошел бы намного быстрее, если бы я видел что не так.
В настоящее время я динамично загружаю длинный список функций от DLL, который я сделал. Путем я настроил вещи, указатели функции имеют тот же nanes как экспортируемые функции, и определение (определения) типа раньше моделировало их, имеют те же имена, но с предварительно ожидаемым подчеркиванием. Таким образом, я хочу использовать определение для упрощения присвоений длинного длинного списка указателей функции.
Например, В положении кода ниже, 'hexdump' является названием typedef'd единицы функциональности и является также названием функции, в то время как _hexdump является названием определения типа. Если GetProcAddress () сбои, отказ противостоит в увеличенном.
if (!(hexdump = (_hexdump)GetProcAddress(h, "hexdump"))) --iFail;
Так скажем, я хотел бы заменить каждую строку как вышеупомянутое с макросом, как это...
GETADDR_FOR(hexdump )
Хорошо это является лучшим, я придумал до сих пор. Это не работает (мой//, комментарий должен только предотвратить текстовое форматирование в сообщении)...
// #define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) --iFail;
И снова, в то время как я ЦЕНИЛ бы понимание, какую глупую ошибку я сделал, она сделала бы мой день, чтобы иметь утилиту, которая покажет мне ошибку моих путей путем простого включения моего макроса.
Вы можете просто прогнать свой код через препроцессор, который покажет вам, во что он будет расширен (или выплюнет ошибки, если это необходимо):
$ 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
.
Вы, кажется, не понимаете, каков точный синтаксис для преобразования строк или вставки токенов в макросы препроцессора C.
Вы можете найти эту страницу о макросах препроцессора C в целом полезной.
В частности, я думаю, что этот макрос должен выглядеть так:
#define GETADDR_FOR(a) if (!(a = (_##a)GetProcAddress(h, #a))) --iFail
Завершающий ;
следует пропустить, потому что вы, вероятно, наберете его как GETADDR_FOR (hexdump);
, а если вы этого не сделаете, это будет выглядеть очень странно в вашем C-коде и сбивать с толку многие средства выделения синтаксиса.
Как уже упоминалось, gcc -E
запустит препроцессор и пропустит другие шаги компиляции. Это полезно для отладки проблем препроцессора.
Возможно, вы захотите взглянуть на Boost Wave. Как и большинство Boost, это скорее библиотека, чем утилита, но в ней есть драйвер, выполняющий роль полноценного препроцессора.