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 sig-
     nature string describing the function to be called	back (see manual or
     dyncall_signature.h for format). This is needed for dyncallback dyncall-
     back 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 defini-
     tion 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 simplic-
     ity, this example will omit passing it as a function pointer to a func-
     tion (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>

				  May 6, 2018