Подскажите, как написать макрос на цэ, чтобы он мог принимать неопределенное кол-во аргументов. На асме я рипал код invoke: Код (Text): macro doitf proc,[arg] ; indirectly call STDCALL procedure { common if ~ arg eq reverse pushd arg common end if ... как это сделать с помощью #define?
!google macros+ellipsis+define+c -> мне повезет http://msdn2.microsoft.com/en-us/library/ms177415(VS.80).aspx
#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))
чтобы не быть голословным объясню задачу.. надо чтобы макрос ложил в стек все переданные аргументы (сколько бы их нибыло) и потом делал call <первый аргумент>. написал примерно так: Код (Text): #define doitf(fapi,...) _asm{push __VA_ARGS__;call fapi;} но чето не работает.. никак от асма не могу отвыкнуть, помогите
глянь генерируемый код, думаю там несложно. заодно можешь енумератор выложить правда малопонятен смысл использования эллипсисов. лучше заменить чем-нибудь более надежным.
по pushargEx всего 6 ссылок и все только код.. пока толком не пойму как это работает later: хотя.. вроде понял, похоже то, что надо
// для функции с одним аргументом template <DWORD fapi, DWORD api, class A> inline LPVOID pushargEx(A a1) { __asm {push a1; mov EAX,api; call fapi} } ну и так далее для нескольких аргументов.. не красиво как-то =\
Чудак-человек. Чем стандартный вариант не подходит? Компилятор сделает то же самое, но без асм-вставок. Код (Text): // для функции с одним аргументом template <typename F, typename A> inline void* pushargEx(F api, A a1) { typedef void* (WINAPI *newfunc)(A); return newfunc(api)(a1); } void f() { void* p = CloseHandle; pushargEx(p, 1); }
вот чо генерит ваш любимый цэ: Код (Text): 004114E0 55 PUSH EBP 004114E1 8BEC MOV EBP,ESP 004114E3 83EC 40 SUB ESP,40 004114E6 53 PUSH EBX 004114E7 56 PUSH ESI 004114E8 57 PUSH EDI 004114E9 33C0 XOR EAX,EAX 004114EB 5F POP EDI 004114EC 5E POP ESI 004114ED 5B POP EBX 004114EE 8BE5 MOV ESP,EBP 004114F0 5D POP EBP 004114F1 C3 RETN то есть фактически ничего :'( later: работает пока так..
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 апя, в стеке ее параметры и валидный адрес возврата, теперь можно над ней поизвращаться }
a1ss Клевещешь: Код (Text): // int main() { f(); return 0; } .text:00401010 _main proc near ; CODE XREF: start+16Ep .text:00401010 push 1 ; hObject .text:00401012 call ds:CloseHandle .text:00401018 xor eax, eax .text:0040101A retn .text:0040101A _main endp // без оптимизации .text:00401030 ; void *__cdecl pushargex(void *api, void *arg) .text:00401030 pushargex proc near ; CODE XREF: f+12p .text:00401030 .text:00401030 api = dword ptr 8 .text:00401030 arg = dword ptr 0Ch .text:00401030 .text:00401030 push ebp .text:00401031 mov ebp, esp .text:00401033 mov eax, [ebp+arg] .text:00401036 push eax .text:00401037 call [ebp+api] .text:0040103A pop ebp .text:0040103B retn .text:0040103B pushargex endp
Ога.. Странное свойство студии, редактируешь код, билдишь проект, а в бинарнике все так же. Пока не перезагрузил студию так и генерил то жп самое. Может сам чото не то делою =\