My C program uses callback functions which are periodically called. I want to be able to handle the callback functions in a Java or C# program. How should I write the .i file to achieve this?
The C callback looks so:
static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata)
You can do this if you have a chance to pass some data around with the callback, but you’ll need to write some JNI glue. I put together a complete example of how you might map C style callbacks onto a Java interface.
The first thing you need to do is decide on an interface that’s appropriate on the Java side. I assumed in C we had callbacks like:
I decided to represent that in Java as:
(The loss of the
void *userdataon the Java side isn’t a real problem since we can store state in theObjectthat implementsCallbacktrivially).I then wrote the following header file (it shouldn’t really be just a header, but it keeps things simple) to exercise the wrapping:
I was able to successfully wrap this C with the following interface:
The interface has quite a few parts to it:
structto store the information needed to make a call to the Java interface.callback_t. It accepts as user data thestructwe just defined and then dispatches a call to the Java interface using some standard JNI.Callbackobjects to be passed straight to the C implementation as a realjobject.void*on the Java side and sets up acallbackdata and fills in the corresponding arguments for the real function to use the function we just wrote for dispatching calls back to Java. It takes a global reference to the Java object to prevent it from being garbage collected subsequently.I wrote a little Java class to test it with:
which worked as you’d hope.
Some points to note:
setmultiple times it will leak the global reference. You either need to supply a way for the callback to be unset, prevent setting multiple times, or use weak references instead.JNIEnvthan I’ve been here.%constantbut these typemaps will prevent your wrapped functions from accepting such inputs. Probably you would want to supply overloads to work around that.There’s some more good advice in this question.
I believe that a solution for C# would be somewhat similar, with different typemap names and a differing implementation of the callback function you write in C.