Макросы и вызов функций по указателям (cpp)

Тема в разделе "LANGS.C", создана пользователем Rel, 24 май 2010.

  1. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    в некотором коде вызовы определенных функций происходят следующим образом, например:
    Код (Text):
    1. CALL(GetProcessHeap());
    сам макрос:
    Код (Text):
    1. #define CALL(Function) p##Function
    где p##Function - переменная, содержащая адрес функции... теперь вопрос... можно ли модифицировать макрос вызова так, чтобы до попытки вызова происходила проверка валидности указателя (то есть NULL или не NULL), и если указатель не валиден на место функции вставлялось бы что-то типа ((void)0)? самая загвоздка состоит в том, что такой метод вызова должен быть способен участвовать в следующих выражениях:
    Код (Text):
    1. 1) CALL(Function(...));
    2. 2) TYPE Var = CALL(Function(...));
    3. 3) if(CALL(Function(...))) { ... }
    есть какие-нибудь идеи? заранее спасибо за помощь...
     
  2. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    а, ещё об одном забыл упомянуть... думал сделать через (условие ? вариант1 : вариант2), но не подходит для самого первого выражения... вообще в идеале туда бы блок try-catch засунуть, но чет мне кажется, что это невозможно...
     
  3. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    а для чего вобще это может быть нужно?
     
  4. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    ну функции из DLL вызываются по указателю... GetProcessHeap просто для примера привел... там как бы два варианта сборки проекта есть, статический, когда DLL собирается вместе с EXE, и динамический, когда EXE использует код "извне"... но в коде вызовы выглядят одинаково:
    Код (Text):
    1. #ifdef ...
    2. #define CALL(Function) p##Function
    3. #else
    4. #define CALL(Function) Function
    5. #endif
     
  5. freeq

    freeq New Member

    Публикаций:
    0
    Регистрация:
    2 дек 2008
    Сообщения:
    47
    тоже не особо понял, скорее всего апи по хешу вызываются, тогда легче в самой ф-ции сделать которая их получает проверку на NULL и возвращать 0x000000.
    И зачем усложнять себе жизнь всякими CALL() ? пишите хотябы "p" в переди облегчите набор букв или тогда сразу на асме если прет синтаксис :)
     
  6. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    ну как сказать... в принципе, кроме всяких частностей, типа той, о которой я спрашиваю в этой теме, языку цпп не хватает только свойства рефлексивности))) имхо канеш...
     
  7. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    имхо лучше постбилд утилиту сделать в которой преобразовывать импорт к нужному виду (хеши или что там нужно), останется добавить только мелкий стаб чтобы все настроить (фиксапы, импорт)
     
  8. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    Rel
    нельзя, т.к. Function это не имя, а имя+аргументы

    можно что-то типа
    #define CALL(name, ...) p##name ? (void)0 : p##name(__VA_ARGS__)
     
  9. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    так... господа, давайте не будем говорить, как будет лучше, а будем решать проблему... я бы тоже делал по-другому, хотя и этот вариант весьма не плох в плане удобства... единственный косяк - отсутствие проверки на валидность указателя... к сожалению меня никак не осинит, как решить эту проблему, поэтому прошу здесь о помощи... если такое возможно сделать в принципе...
     
  10. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    GoldFinch
    да... вот это интересно... попробую покрутить что-нить с этим... спасибо!
     
  11. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    GoldFinch
    похоже это сработает везде, кроме выражений первого типа (см. #1)... но идея мне нравится)))
     
  12. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    придется ведь объявлять сотни указателей на функции
    в этом есть какой-то скрытый смысл или я что-то не понимаю?
     
  13. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    не берите в голову... все в порядке...
     
  14. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    Rel

    ?

    Код (Text):
    1. typedef int (WINAPI*PFN)(HWND, LPCSTR, LPCSTR, UINT);
    2. static PFN pMessageBoxA;
    3.  
    4. #define CALL(Function, ...) p##Function ? p##Function (__VA_ARGS__) : 0
    5.  
    6. typedef int TYPE;
    7.  
    8. int main(void)
    9. {
    10.     TYPE Var;
    11.     HMODULE hMod = LoadLibrary("user32");
    12.     pMessageBoxA = (PFN)GetProcAddress(hMod, "MessageBoxA");
    13.     CALL(MessageBoxA, 0, "1", 0, 0);
    14.     Var = CALL(MessageBoxA, 0, "2", 0, 0);
    15.     if(CALL(MessageBoxA, 0, "3", 0, 0))
    16.         puts("good job $100000");
    17.     else
    18.         puts("you not need money ?");
    19.     FreeLibrary(hMod);
    20. }