RE: Callback problem
- Posted by Andy Serpa <ac at onehorseshy.com> Oct 13, 2002
- 360 views
stabmaster_ at hotmail.com wrote: > >This sounds like the cdecl-stdcall problem. > >... > >There probably is a way to fix it by poking assembly. > > > >Karl Bochert > > > I did just that in Glue, my GLUT wrapper for Euphoria. In glue.e there > is a > function called cdecl_callback that takes a routine_id and a sequence of > > parameter sizes (in bytes). E.g. if you have a function foo that takes 3 > > integer parameters, you'd do something like: > > atom my_callback > my_callback = cdecl_callback(routine_id("foo"),{4,4,4,4}) > > Note that i passed 4 4's, this is intentionally. You see, there's a > small > problem: Since EIP is pushed on the stack after the parameters, you'll > get > the return address in the first parameter of your function. To get > around > this you must prepend a dummy argument to your function. I.e. if you > had: > > function foo(integer a,integer b,integer c) > > You'd have to change it to: > > function foo(integer dummy,integer a,integer b,integer b) > > It works! Here is the basic assembler your routine generates: #B8,#00,#00,#00,#00, -- 0: mov eax,callback (1) #FF,#D0, -- 5: call near eax #83,#EC,#00, -- 7: sub esp, 0 #C3 -- A: ret So, you replace the "#00,#00,#00,#00" with the 4-byte call_back() address of your routine, and then replace the #00 in line 7 with the number of args * 4 (dummy argument included). Works like a charm!