ammer

Callbacks

Callbacks allow native libraries to call Haxe code, for example, to invoke a handler when an event happens. Callbacks in C generally belong to two categories:

In ammer, a callback is declared using the ammer.ffi.Callback<...> type, which has 5 type parameters:

ammer.ffi.Callback<
  CallbackType,
  FunctionType,
  CallTarget,
  CallArgs,
  Lib
>

The type parameters should be filled in as follows:

It may be convenient to typedef callback types when referring to them within ammer definitions.

Example: declaring and using a callback type

Assuming a C library with the following implementation:

// Type alias for the function type.
// It receives two integer arguments, in addition to the user-defined context.
int32_t (* callback_type)(int32_t, int32_t, void*);

static callback_type *stored_fptr = NULL;
static void *stored_context = NULL;

void store_callback(callback_type *fptr, void *call_context) {
  stored_fptr = fptr;
  stored_context = call_context;
}

int32_t invoke_callback(int32_t a, int32_t b) {
  return stored(a, b, stored_context);
}

The callback type can be reflected in ammer as follows:

typedef CallbackType = ammer.ffi.Callback<
  (ammer.ffi.Int32, ammer.ffi.Int32, Haxe<(Int, Int)->Int>)->ammer.ffi.Int32,
  (Int, Int)->Int,
  [arg2],
  [arg0, arg1],
  Foobar
>;

Note that [arg2] refers to the third, void*-typed argument of callback_type, whereas [arg0, arg1] refer to the first two, int-typed arguments.

The ammer definition for the C library above may look like this:

class Foobar extends ammer.def.Library<"foobar"> {
  public static function store_callback(_:CallbackType, _:ammer.ffi.Haxe<(Int, Int)->Int>):Void;
  public static function invoke_callback(_:ammer.ffi.Int32, _:ammer.ffi.Int32):ammer.ffi.Int32;
}

Finally, an example of using the library to invoke the callback:

var func = (a:Int, b:Int) -> { return a + b; };
var funcRef = ammer.Lib.createHaxeRef(func);
funcRef.incref();
Foobar.store_callback(funcRef);

// ...

trace(Foobar.invoke_callback(1, 2)); // 3

Note the use of createHaxeRef: func is an instance of a Haxe type, thus it must be wrapped with a reference counter as explained in the Haxe types section.

« Previous: Haxe types Next: Linking subdefinitions »