макросы

Тема в разделе "LANGS.C", создана пользователем a1ss, 10 апр 2008.

  1. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    Подскажите, как написать макрос на цэ, чтобы он мог принимать неопределенное кол-во аргументов. На асме я рипал код invoke:

    Код (Text):
    1. macro doitf proc,[arg]          ; indirectly call STDCALL procedure
    2. { common
    3.   if ~ arg eq
    4.   reverse
    5.   pushd arg
    6.   common
    7.   end if  
    8.   ...
    :) как это сделать с помощью #define?
     
  2. Noble Ghost

    Noble Ghost New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2004
    Сообщения:
    204
    Адрес:
    Russia
    #define SOME_MACROS(...)
    afair
     
  3. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    че это? и как обращаться к переменным?
     
  4. Noble Ghost

    Noble Ghost New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2004
    Сообщения:
    204
    Адрес:
    Russia
    afair = as far, as I remember :)
    к аргументам через VA_ARGS, возможно с подчерками.
     
  5. Noble Ghost

    Noble Ghost New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2004
    Сообщения:
    204
    Адрес:
    Russia
    !google macros+ellipsis+define+c -> мне повезет

    http://msdn2.microsoft.com/en-us/library/ms177415(VS.80).aspx
     
  6. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    #define CHECK3(s,...) { printf(s,__VA_ARGS__); }

    здесь понятно, печатаются все переданные параметры:
    CHECK3("here %s %s %s", "are", "some", "varargs3(5)\n"); >>>>>> here are some varargs3(5)

    а как в этом случае сделать так, чтобы макрос напчатал например только 1-ую и 3-юю переменные? т.е.так:
    (here are varargs3(5))
     
  7. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    чтобы не быть голословным объясню задачу.. надо чтобы макрос ложил в стек все переданные аргументы (сколько бы их нибыло) и потом делал call <первый аргумент>. написал примерно так:

    Код (Text):
    1. #define  doitf(fapi,...) _asm{push __VA_ARGS__;call fapi;}
    но чето не работает.. никак от асма не могу отвыкнуть, помогите :)
     
  8. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Погугли по pushargex, может, шаблоны помогут.
     
  9. Noble Ghost

    Noble Ghost New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2004
    Сообщения:
    204
    Адрес:
    Russia
    глянь генерируемый код, думаю там несложно.
    заодно можешь енумератор выложить :)

    правда малопонятен смысл использования эллипсисов. лучше заменить чем-нибудь более надежным.
     
  10. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    по pushargEx всего 6 ссылок и все только код.. пока толком не пойму как это работает

    later:
    хотя.. вроде понял, похоже то, что надо
     
  11. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    // для функции с одним аргументом

    template <DWORD fapi, DWORD api, class A>
    inline LPVOID pushargEx(A a1)
    {
    __asm {push a1; mov EAX,api; call fapi}
    }

    ну и так далее для нескольких аргументов.. не красиво как-то =\
     
  12. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Чудак-человек. Чем стандартный вариант не подходит? Компилятор сделает то же самое, но без асм-вставок.

    Код (Text):
    1. // для функции с одним аргументом
    2. template <typename F, typename A>
    3. inline void* pushargEx(F api, A a1)
    4. {
    5.     typedef void* (WINAPI *newfunc)(A);
    6.     return newfunc(api)(a1);
    7. }
    8.  
    9. void f()
    10. {
    11.     void* p = CloseHandle;
    12.     pushargEx(p, 1);
    13. }
     
  13. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    вот чо генерит ваш любимый цэ:

    Код (Text):
    1. 004114E0    55              PUSH EBP
    2. 004114E1    8BEC            MOV EBP,ESP
    3. 004114E3    83EC 40         SUB ESP,40
    4. 004114E6    53              PUSH EBX
    5. 004114E7    56              PUSH ESI
    6. 004114E8    57              PUSH EDI
    7. 004114E9    33C0            XOR EAX,EAX
    8. 004114EB    5F              POP EDI
    9. 004114EC    5E              POP ESI
    10. 004114ED    5B              POP EBX
    11. 004114EE    8BE5            MOV ESP,EBP
    12. 004114F0    5D              POP EBP
    13. 004114F1    C3              RETN
    то есть фактически ничего :'(

    later:
    работает пока так..
     
  14. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    template <typename F, typename A>
    inline void* pushargEx(F api, A a1)
    {
    __asm {push a1
    call executeapifake+9};
    }


    ...


    pushargEx(pAPI[13],0);


    ...

    DWORD executeapifake()
    {
    return(0); //а тут у меня в EAX апя, в стеке ее параметры и валидный адрес возврата, теперь можно над ней поизвращаться ;)
    }
     
  15. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    a1ss
    Клевещешь:
    Код (Text):
    1. // int main() {  f(); return 0; }
    2. .text:00401010 _main           proc near               ; CODE XREF: start+16Ep
    3. .text:00401010                 push    1               ; hObject
    4. .text:00401012                 call    ds:CloseHandle
    5. .text:00401018                 xor     eax, eax
    6. .text:0040101A                 retn
    7. .text:0040101A _main           endp
    8.  
    9. // без оптимизации
    10. .text:00401030 ; void *__cdecl pushargex(void *api, void *arg)
    11. .text:00401030 pushargex       proc near               ; CODE XREF: f+12p
    12. .text:00401030
    13. .text:00401030 api             = dword ptr  8
    14. .text:00401030 arg             = dword ptr  0Ch
    15. .text:00401030
    16. .text:00401030                 push    ebp
    17. .text:00401031                 mov     ebp, esp
    18. .text:00401033                 mov     eax, [ebp+arg]
    19. .text:00401036                 push    eax
    20. .text:00401037                 call    [ebp+api]
    21. .text:0040103A                 pop     ebp
    22. .text:0040103B                 retn
    23. .text:0040103B pushargex       endp
     
  16. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    Ога.. Странное свойство студии, редактируешь код, билдишь проект, а в бинарнике все так же. Пока не перезагрузил студию так и генерил то жп самое. Может сам чото не то делою =\
     
  17. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    у тебя чето не то с датами мб?
     
  18. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    хз, нада поэкспериментировать..
     
  19. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    a1ss
    У меня так было
    пока не стал замечать, что в Output выводились ошибки, мною допущенные :)
     
  20. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    KeSqueer сочуствую..)) но у меня проблема не в этом.. пока еще не разобрался