This is the mail archive of the libffi-discuss@sources.redhat.com mailing list for the libffi project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;
}




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]