dyncall library - C foreign function interface dyncall library: home - news - download - source/repository - bindings - documentation - license - credits - showcase/users - contact University of Göttingen 3ds Max, Maya Plugin Development - Potion Studios




     dyncallback – callback interface of dyncall


     #include <dyncall_callback.h>

     DCCallback *
     dcbNewCallback(const char * signature, DCCallbackHandler * funcptr,
         void * userdata);

     dcbInitCallback(DCCallback * pcb, const char * signature,
         DCCallbackHandler * funcptr, void * userdata);

     dcbFreeCallback(DCCallback * pcb);

     dcbGetUserData(DCCallback * pcb);


     The dyncallback dyncall library has an interface to create callback
     objects, that can be passed to functions as callback arguments. In other
     words, a pointer to the callback object can be "called", directly. The
     callback handler then allows iterating dynamically over the arguments
     once called back.

     dcbNewCallback() creates a new callback object, where signature is a
     signature string describing the function to be called back (see manual or
     dyncall_signature.h for format). This is needed for dyncallback
     dyncallback to correctly prepare the arguments passed in by the function
     that calls the callback handler. Note that the handler doesn't return the
     value specified in the signature, directly, but a signature character,
     specifying the return value's type.  The return value itself is stored
     where the handler's 3rd parameter points to (see below).  funcptr is a
     pointer to the dyncallback dyncallback callback handler (see below), and
     userdata a pointer to arbitrary user data you want to use in the callback
     handler.  Use the returned pointer as callback argument in functions
     requiring a callback function pointer.

     dcbInitCallback() (re)initialize the callback object.

     dcbFreeCallback() destroys and frees the callback handler.

     dcbGetUserData() returns a pointer to the userdata passed to the callback
     object on creation or initialization.

     Declaration of a dyncallback handler (following function pointer
     definition in dyncallback/dyncall_callback.h):

           char cbHandler(DCCallback* cb,
                          DCArgs*     args,
                          DCValue*    result,
                          void*       userdata);

     cb is a pointer to the DCCallback object in use dyncallback result is a
     pointer to a DCValue object in order to store the callback's return value
     (output, to be set by handler). Finally, userdata is a pointer to some
     user defined data that can be set when creating the callback object.  The
     handler itself returns a signature character (see manual for format)
     specifying the data type used for result.


     Let's say, we want to create a callback object and call it. For
     simplicity, this example will omit passing it as a function pointer to a
     function (e.g. compar in qsort(), etc.) and demonstrate calling it,
     directly. First, we need to define our callback handler - the following
     handler illustrates how to access the passed- in arguments:

           char cbHandler(DCCallback* cb,
                          DCArgs*     args,
                          DCValue*    result,
                          void*       userdata)
             int* ud = (int*)userdata;
             int       arg1 = dcbArgInt     (args);
             float     arg2 = dcbArgFloat   (args);
             short     arg3 = dcbArgShort   (args);
             double    arg4 = dcbArgDouble  (args);
             long long arg5 = dcbArgLongLong(args);

             // .. do something ..

             result->s = 1244;
             return 's';

     Note that the return value of the handler is a signature character, not
     the actual return value, itself.  Now, let's call it through a DCCallback

             DCCallback* cb;
             short result = 0;
             int userdata = 1337;
             cb = dcbNewCallback("ifsdl)s", &cbHandler, &userdata);
             result = ((short(*)(int, float, short, double, long long))cb)
               (123, 23.f, 3, 1.82, 9909ll);


     The dyncallback library needs at least a c99 compiler with additional
     support for anonymous structs/unions (which were introduced officially in
     c11). Given that those are generally supported by pretty much all major
     c99 conforming compilers (as default extension), it should build fine
     with a c99 toolchain.  Strictly speaking, dyncall conforms to c11,


     dyncall(3), dynload(3) and the dyncall manual (available in HTML and PDF
     format) for more information.


     Daniel Adler ⟨dadler@uni-goettingen.de⟩
     Tassilo Philipp ⟨tphilipp@potion-studios.com⟩

                               January 12, 2020