в некотором коде вызовы определенных функций происходят следующим образом, например: Код (Text): CALL(GetProcessHeap()); сам макрос: Код (Text): #define CALL(Function) p##Function где p##Function - переменная, содержащая адрес функции... теперь вопрос... можно ли модифицировать макрос вызова так, чтобы до попытки вызова происходила проверка валидности указателя (то есть NULL или не NULL), и если указатель не валиден на место функции вставлялось бы что-то типа ((void)0)? самая загвоздка состоит в том, что такой метод вызова должен быть способен участвовать в следующих выражениях: Код (Text): 1) CALL(Function(...)); 2) TYPE Var = CALL(Function(...)); 3) if(CALL(Function(...))) { ... } есть какие-нибудь идеи? заранее спасибо за помощь...
а, ещё об одном забыл упомянуть... думал сделать через (условие ? вариант1 : вариант2), но не подходит для самого первого выражения... вообще в идеале туда бы блок try-catch засунуть, но чет мне кажется, что это невозможно...
ну функции из DLL вызываются по указателю... GetProcessHeap просто для примера привел... там как бы два варианта сборки проекта есть, статический, когда DLL собирается вместе с EXE, и динамический, когда EXE использует код "извне"... но в коде вызовы выглядят одинаково: Код (Text): #ifdef ... #define CALL(Function) p##Function #else #define CALL(Function) Function #endif
тоже не особо понял, скорее всего апи по хешу вызываются, тогда легче в самой ф-ции сделать которая их получает проверку на NULL и возвращать 0x000000. И зачем усложнять себе жизнь всякими CALL() ? пишите хотябы "p" в переди облегчите набор букв или тогда сразу на асме если прет синтаксис
ну как сказать... в принципе, кроме всяких частностей, типа той, о которой я спрашиваю в этой теме, языку цпп не хватает только свойства рефлексивности))) имхо канеш...
имхо лучше постбилд утилиту сделать в которой преобразовывать импорт к нужному виду (хеши или что там нужно), останется добавить только мелкий стаб чтобы все настроить (фиксапы, импорт)
Rel нельзя, т.к. Function это не имя, а имя+аргументы можно что-то типа #define CALL(name, ...) p##name ? (void)0 : p##name(__VA_ARGS__)
так... господа, давайте не будем говорить, как будет лучше, а будем решать проблему... я бы тоже делал по-другому, хотя и этот вариант весьма не плох в плане удобства... единственный косяк - отсутствие проверки на валидность указателя... к сожалению меня никак не осинит, как решить эту проблему, поэтому прошу здесь о помощи... если такое возможно сделать в принципе...
GoldFinch похоже это сработает везде, кроме выражений первого типа (см. #1)... но идея мне нравится)))
придется ведь объявлять сотни указателей на функции в этом есть какой-то скрытый смысл или я что-то не понимаю?
Rel ? Код (Text): typedef int (WINAPI*PFN)(HWND, LPCSTR, LPCSTR, UINT); static PFN pMessageBoxA; #define CALL(Function, ...) p##Function ? p##Function (__VA_ARGS__) : 0 typedef int TYPE; int main(void) { TYPE Var; HMODULE hMod = LoadLibrary("user32"); pMessageBoxA = (PFN)GetProcAddress(hMod, "MessageBoxA"); CALL(MessageBoxA, 0, "1", 0, 0); Var = CALL(MessageBoxA, 0, "2", 0, 0); if(CALL(MessageBoxA, 0, "3", 0, 0)) puts("good job $100000"); else puts("you not need money ?"); FreeLibrary(hMod); }