This is the mail archive of the
libffi-discuss@sources.redhat.com
mailing list for the libffi project.
minimal closure usage
- From: "Sam Liddicott" <sam dot liddicott at ananova dot com>
- To: "Anthony Green" <green at redhat dot com>, "Sam Liddicott" <sam dot liddicott at ananova dot com>
- Cc: <libffi-discuss at sources dot redhat dot com>
- Date: Tue, 30 Apr 2002 10:37:14 +0100
- Subject: minimal closure usage
Unlike many uses of libffi where the calling parameters are not know until
runtime and therefore ffi_cif is a must, swig knows what the paramters will
be at compile time but just needs some way to squeeze an extra context
pointer back in when the call is made.
Is there a simpler way to preserve all the old arguments but prepend or
append the user_data as an additional one? Or does the wrapped function
have to have a calling signature of (ffi_cif*, void*, void**, void*)?
If the answer is no, I think this the minimal code to use a closure to wrap
a callback-wrapper-that-can-take-the-extra-context-pointer which is used to
direct the callback to the scripting system:
(BTW: Is there an array/structure/function/full-set-of-rules to convert
between "int" and "ffi_type_sint" etc? SWIG would need to refer to this as
it generates the sample code below)
// DECLARE OR DO ALL THIS AT LOAD TIME
// SWIG-generated wrapper-wrapper function, one for each function signature
// Convert back to standard parameters to save headaches
void callback_wrapper_wrapper(ffi_cif*, void* resp, void** args, void*
userdata) {
*($RETURN_TYPE*) = callback_wrapper(userdata,
*($arg0_type*)args[0],
*($arg1_type*)args[1],
...);
}
// cif for this callback signature handler, and arg-types for the same
ffi_cif callback_wrapper_wrapper_cif;
ffi_type * callback_wrapper_wrapper_args[$numargs+1];
// $type2ffi represents some conversion function to convert
// from words like "int" to words like "ffi_type_sint"
// which SWIG will rely on as it writes out the code below
callback_wrapper_wrapper_args[0]=$type2ffi($arg0_type);
callback_wrapper_wrapper_args[1]=$type2ffi($arg1_type);
...
callback_wrapper_wrapper_args[$numargs]=NULL;
ffi_prep_cif(&callback_wrapper_wrapper_cif, FFI_DEFAULT_ABI, $numargs,
$type2ffi($return_type), callback_wrapper_wrapper_args);
//----------------------
// AND THEN DO THIS EACHTIME A CALLBACK OF THAT TYPE IS NEEDED
void* allocCallback_of_certain_type(type_of_function_to_be_wrapped*
to_be_wrapped, void* userdata) {
ffi_closure *callback_wrapper_wrapper_closure =
malloc(sizeof(ffi_closure));
ffi_prep_closure(callback_wrapper_wrapper_closure,
&callback_wrapper_wrapper_cif,
to_be_wrapped, userdata);
return callback_wrapper_wrapper_closure;
}