Хочу чудо-макрос

Тема в разделе "LANGS.C", создана пользователем 7mm, 11 ноя 2010.

  1. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Друзья, подскажите кто знает, как такое чудо на MSVC реализовать:

    Код (Text):
    1. #define API_TYPE_F VOID
    2. #define API_ADDR_F 0x00123456
    3.  
    4. API_CALL(F, Arg1, Arg2, ...);
    Чтобы в итоге было нечто такое:

    Код (Text):
    1. ((API_TYPE_F (*)(Type1, Type2, ...))API_ADDR_F)(Arg1, Arg2, ...);
    UPD: Или на крайняк такое:

    Код (Text):
    1. ((API_TYPE_F (*)(DWORD, DWORD, ...))API_ADDR_F)(Arg1, Arg2, ...);
     
  2. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    Гугл: variadic macros
     
  3. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Код (Text):
    1. #define API_CALL(F, ...) \
    2.     ((API_TYPE_##F (*)(X(__VA_ARGS__)))API_ADDR_##F)(__VA_ARGS__)
    Осталось придумать как при помощи макроса X(...) формировать список типов :)
     
  4. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Гугл как-то уж размывчато выдаёт как такое сделать :dntknw:
     
  5. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    не проще ли сделать на темплейтах?
     
  6. Mentor

    Mentor New Member

    Публикаций:
    0
    Регистрация:
    13 окт 2010
    Сообщения:
    67
    boost/typeof
    хотя, пушкой по воробьям, конечно
     
  7. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Да не, мне макрос бы...
     
  8. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    А как ты типы выяснять собираешься? По типу передаваемых аргументов?
    Напиши несколько макросов, на разное количество аргументов. А дальше оператором typeof.
     
  9. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Типы - хрен с ними. К тому же, похоже c typeof у MSVC/C++ какие-то проблемы, через одно место. Также выяснилось, что у __VA_ARGS__ и ellipsis (...) есть одна интересная особенность: они НЕ позволяют передавать пустой список параметров. Компилятор ругается с ошибкой. Причём, команда, занимающаяся компилятором об этом типа знает, но т.к. это не совсем баг, а так и задумано, то вот уже 2 года не спешит его править. Мне почему пустой список нужен - это вызов функции без параметров. Короче, MSVC это вещь в себе какая-то...
     
  10. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
  11. GoldFinch

    GoldFinch New Member

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

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    все нормально с пустым списком аргументов... возможно с руками что-то не в порядке)))
     
  13. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Оки, дайте макрос подсчёта количества параметров: если нет ничего - 0, иначе {1,2,3,...} ?
     
  14. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    __noop ошибку убирает
     
  15. Rel

    Rel Well-Known Member

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

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    http://stackoverflow.com/questions/2308243/macro-returning-length-of-arguments-in-c
     
  17. osox

    osox New Member

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

    1) для с++
    Код (Text):
    1. #define TF VOID
    2. #define AF 0xcccccccc
    3.  
    4. #define C(F,...) ((T##F(*)(...))A##F)(__VA_ARGS__)
    5.  
    6. int main(){
    7.     C(F);
    8.     C(F,"s",678.f);
    9.     C(F,987,"s",234);
    10.     C(F,876.f,123,876,"s");
    11.     C(F,876,"s",234.f,876,234);
    12.     C(F,876,123,"s",876,678,77.88f);
    13. }
    2) для си удалите ...
    Код (Text):
    1. #define TF VOID
    2. #define AF 0xcccccccc
    3.  
    4. #define C(F,...) ((T##F(*)())A##F)(__VA_ARGS__)
    5.  
    6. int main(){
    7.     C(F);
    8.     C(F,"s",678.f);
    9.     C(F,987,"s",234);
    10.     C(F,876.f,123,876,"s");
    11.     C(F,876,"s",234.f,876,234);
    12.     C(F,876,123,"s",876,678,77.88f);
    13. }
     
  18. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    или надо __stdcall соглашение ?
     
  19. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    >>макросы - зло.
    +пицот. Хоть иногда дельное говорит ! ;)))
     
  20. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    osox

    Ух, добрый человек, респект и уважуха! Вот она, формула счастья:
    Код (Text):
    1. #define API_CALL(F, ...) ((API_TYPE_##F (*)(...))API_ADDR_##F)(__VA_ARGS__)