1. Callback problem

>From: Andy Serpa <renegade at earthling.net>
>Subject: RE: Wrapping C - Callback troubles



Bernie Ryan wrote:
> 
> Andy Serpa wrote:
> > Here's another problem.  I'm making the Berkeley DB wrapper=
 which 
allows 
> > for certain callback functions to be used.  One particular=
 one 
I'm 
> > trying to set up is supposed to be a void function.  The=
 callback 
works 
> > (my function is called), but when it returns a value (any=
 value) 
it 
> > crashes.  (Callback functions are required to return=
 something.)  

>But that's not the problem.  Setting the callback function is no=
 
>problem, and my Euphoria function is being called with the=
 correct 
>args. 
 >The problem is when my function exits (returns a value) the=
 whole 
>thing 
>crashes with an exception.  I was just wondering is that because=
 it 
>is a 
>supposed to be void function?  (It seems like I should be able=
 to 
>return 
>anything in that case, but maybe it wants me to return nothing?)=
  
>Anybody know anything about that?

This sounds like the cdecl-stdcall problem. Many packages that=
 come 
from the unix world expect the callback function to be cdecl=
 rather 
than the windows standard stdcall. If the callback is of the=
 wrong 
variety, the stack gets messed up.

I modified Bach to accept cdecl callbacks -- under Euphoria I=
 think 
the easiest option is to modify the calling convention in the=
 source 
and re-compile the package.

There probably is a way to fix it by poking assembly.

Karl Bochert

new topic     » topic index » view message » categorize

2. Re: Callback problem

>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)

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu