Suppose I have a C library with code like this:
typedef int (callback_t)(int);
void register_callback(callback_t cb);
I want to write go bindings for this function and pass arbitrary go callbacks.
I found an excellent answer here. However, it is a trick that makes use of the fact that the callback accepts a void *
, through which Go passes the function pointer to C and receives it back. However, this can't be applied in my example since there isn't a user void *
.
The best I could do is:
/*
extern int gobridge(int data);
static int cbridge(void)
{
register_callback(gobridge);
}
*/
import "C"
type Callback func (int) int
var g_cb Callback
//export gobridge
func gobridge(data C.int) C.int {
return C.int(g_cb(int(data)))
}
func RegisterCallback(cb Callback) {
g_cb = cb //save callback in a global
C.cbridge()
}
func Count(left, right int) {
C.count(C.int(left), C.int(right))
}
This only works for a single register_callback (because of the global variable), but the C library can register many callbacks and invoke them all.
I hoped to achieve something like this, but this doesn't compile (put aside the clojure, it can't convert the go function to c function even though the signature is the same):
import "C"
func RegisterCallback(cb Callback) {
f := func (d C.int) C.int {
return C.int(cb(int(d)))
}
C.register_callback(f)
}
func Count(left, right int) {
C.count(C.int(left), C.int(right))
}
Is there a way to properly bind the C library?