diff dyncallback/dyncallback.3 @ 533:71c884e610f0

- integration of patches from Raphael Luba, Thekla, Inc.: * integration of aggregate-by-value (struct, union) support patch for x64 (win and sysv) * windows/x64 asm additions to specify how stack unwinds (help for debuggers, exception handling, etc.) * see Changelog for details - new calling convention modes for thiscalls (platform agnostic, was specific before) * new signature character for platform agnostic thiscalls ('*' / DC_SIGCHAR_CC_THISCALL) - dcCallF(), dcVCallF(), dcArgF() and dcVArgF(): * added support for aggregates-by-value (wasn't part of patch) * change that those functions don't implicitly call dcReset() anymore, which was unflexible (breaking change) - added macros to feature test implementation for aggregate-by-value and syscall support - changed libdyncall_s.lib and libdyncallback_s.lib order in callback test makefiles, as some toolchains are picky about order - doc: * man page updates to describe aggregate interface * manual overview changes to highlight platforms with aggregate-by-value support - test/plain: replaced tests w/ old/stale sctruct interface with new aggregate one
author Tassilo Philipp
date Thu, 21 Apr 2022 13:35:47 +0200
parents e2899b4ff713
children 111236b31c75
line wrap: on
line diff
--- a/dyncallback/dyncallback.3	Sat Apr 16 15:00:58 2022 +0200
+++ b/dyncallback/dyncallback.3	Thu Apr 21 13:35:47 2022 +0200
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2007-2014 Daniel Adler <dadler AT uni-goettingen DOT de>, 
+.\" Copyright (c) 2007-2022 Daniel Adler <dadler AT uni-goettingen DOT de>, 
 .\"                         Tassilo Philipp <tphilipp AT potion-studios DOT com>
 .\" 
 .\" Permission to use, copy, modify, and distribute this software for any
@@ -21,70 +21,150 @@
 .Sh SYNOPSIS
 .In dyncall_callback.h
 .Ft DCCallback *
-.Fn dcbNewCallback "const char * signature" "DCCallbackHandler * funcptr" "void * userdata"
+.Fn dcbNewCallback "const DCsigchar * signature" "DCCallbackHandler * funcptr" "void * userdata"
+.Ft DCCallback *
+.Fn dcbNewCallback2 "const DCsigchar * signature" "DCCallbackHandler * funcptr" "void * userdata" "DCaggr *const * aggrs"
 .Ft void
-.Fn dcbInitCallback "DCCallback * pcb" "const char * signature" "DCCallbackHandler * funcptr" "void * userdata"
+.Fn dcbInitCallback "DCCallback * pcb" "const DCsigchar * signature" "DCCallbackHandler * funcptr" "void * userdata"
+.Ft void
+.Fn dcbInitCallback2 "DCCallback * pcb" "const DCsigchar * signature" "DCCallbackHandler * funcptr" "void * userdata" "DCaggr *const * aggrs"
 .Ft void
 .Fn dcbFreeCallback "DCCallback * pcb"
 .Ft void
 .Fn dcbGetUserData "DCCallback * pcb"
+.Ft DCbool
+.Fn dcbArgBool "DCArgs * p"
+.Ft DCchar
+.Fn dcbArgChar "DCArgs * p"
+.Ft DCshort
+.Fn dcbArgShort "DCArgs * p"
+.Ft DCint
+.Fn dcbArgInt "DCArgs * p"
+.Ft DClong
+.Fn dcbArgLong "DCArgs * p"
+.Ft DClonglong
+.Fn dcbArgLongLong "DCArgs * p"
+.Ft DCuchar
+.Fn dcbArgUChar "DCArgs * p"
+.Ft DCushort
+.Fn dcbArgUShort "DCArgs * p"
+.Ft DCuint
+.Fn dcbArgUInt "DCArgs * p"
+.Ft DCulong
+.Fn dcbArgULong "DCArgs * p"
+.Ft DCulonglong
+.Fn dcbArgULongLong "DCArgs * p"
+.Ft DCfloat
+.Fn dcbArgFloat "DCArgs * p"
+.Ft DCdouble
+.Fn dcbArgDouble "DCArgs * p"
+.Ft DCpointer
+.Fn dcbArgPointer "DCArgs * p"
+.Ft void
+.Fn dcbArgAggr "DCArgs * p" "DCpointer target"
+.Ft void
+.Fn dcbReturnAggr "DCArgs * args" "DCValue * result" "DCpointer ret"
 .Sh DESCRIPTION
 The
 .Nm
 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.
+to functions as callback function pointers. In other words, a pointer to the
+callback object can be "called", directly. A generic callback handler invoked
+by this object then allows iterating dynamically over the arguments once called
+back.
 .Pp
-.Fn dcbNewCallback
+.Fn dcbNewCallback2
 creates a new callback object, where
 .Ar signature
 is a signature string describing the function to be called back (see manual or
-dyncall_signature.h for format). This is needed for
-.Nm
-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).
+dyncall_signature.h for format), and
 .Ar funcptr
-is a pointer to the
-.Nm
-dyncallback callback handler (see below), and
+is a pointer to a generic callback handler (see below). The signature is needed
+in the generic callback handler to correctly retrieve the arguments provided by
+the caller of the callback. Note that the generic handler's function
+type/declaration is always the same for any callback.
 .Ar 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.
+is a pointer to arbitrary user data to be available in the generic callback
+handler. If the callback expects aggregates (struct, union) to be passed or
+returned by value, a pointer to an array of DCaggr* descriptions must be
+provided (exactly one per aggregate, in the same order as in the signature) via
+the
+.Ar aggrs
+parameter, otherwise pass NULL. This pointer must point to valid data during
+callback.
+.Pp
+.Fn dcbNewCallback
+is the same as
+.Fn dcbNewCallback2 ,
+with an implicit NULL passed via the
+.Ar aggrs
+parameter, meaning it can only be used for callbacks that do not use any
+aggregate by value.
+.Pp
+.Sy NOTE:
+C++ non-trivial aggregates (check with the std::is_trivial type trait) do not
+use any aggregate descriptions, so the respective pointers in the provided
+array must be NULL. See
+.Xr dyncall 3
+for more information on C++ non-trivial aggregates.
+.Pp
+Use the pointer returned by
+.Fn dcbNewCallback*
+as argument in functions requiring a callback function pointer.
 .Pp
 .Fn dcbInitCallback
-(re)initialize the callback object.
+and
+.Fn dcbInitCallback2
+(re)initializes the callback object. For a description of its parameters, see
+.Fn dcbNewCallback* .
 .Pp
 .Fn dcbFreeCallback
 destroys and frees the callback handler.
 .Pp
 .Fn dcbGetUserData
 returns a pointer to the userdata passed to the callback object on creation or
-initialization.
+(re)initialization.
 .Pp
-Declaration of a dyncallback handler (following function pointer definition in
-dyncallback/dyncall_callback.h):
+Declaration of a dyncallback handler (following function pointer declaration in
+dyncall_callback.h):
 .Bd -literal -offset indent
-char cbHandler(DCCallback* cb,
-               DCArgs*     args,
-               DCValue*    result,
-               void*       userdata);
+DCsigchar cbHandler(DCCallback* cb,
+                    DCArgs*     args,
+                    DCValue*    result,
+                    void*       userdata);
 .Ed
 .Pp
-.Ar cb is a pointer to the DCCallback object in use
-.Nm
-result is a pointer to a DCValue object in order to store the callback's
-return value (output, to be set by handler). Finally,
-.Ar 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
+.Ar cb
+is a pointer to the DCCallback object in use,
+.Ar args
+is to be used with the
+.Fn dcbArg*
+functions to iterate over the arguments passed to the callback, and
+.Ar result
+is a pointer to an object used to store the callback's return value (output, to
+be set by the handler). Finally,
+.Ar userdata
+is a pointer to some user defined data that can be set when creating or
+(re)initializing the callback object.
+The handler itself must return a signature character (see manual or
+dyncall_signature.h for format) specifying the data type of
 .Ar result .
+.Pp
+Retrieving aggregates from the generic handler's
+.Ar args
+argument can be done via
+.Fn dcbArgAggr ,
+where
+.Ar target
+must point to memory large enough for the aggregate to be copied to.
+.Pp
+To return an aggregate by value, a helper function
+.Fn dcbReturnAggr
+needs to be used in order to correctly place the aggregate pointed to by
+.Ar ret
+into
+.Ar result ,
+then let the generic handler return DC_SIGCHAR_AGGREGATE.
 .Sh EXAMPLE
 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
@@ -92,10 +172,10 @@
 our callback handler - the following handler illustrates how to access the passed-
 in arguments:
 .Bd -literal -offset indent
-char cbHandler(DCCallback* cb,
-               DCArgs*     args,
-               DCValue*    result,
-               void*       userdata)
+DCsigchar cbHandler(DCCallback* cb,
+                    DCArgs*     args,
+                    DCValue*    result,
+                    void*       userdata)
 {
   int* ud = (int*)userdata;
   int       arg1 = dcbArgInt     (args);
@@ -119,8 +199,11 @@
   short result = 0;
   int userdata = 1337;
   cb = dcbNewCallback("ifsdl)s", &cbHandler, &userdata);
+
+  /* call the callback object */
   result = ((short(*)(int, float, short, double, long long))cb)
     (123, 23.f, 3, 1.82, 9909ll);
+
   dcbFreeCallback(cb);
 .Ed
 .Sh CONFORMING TO