sisoft
sisoft

Reputation: 973

Cgo: can't set callback in C-struct from Go

I have a struct in C lib with some callbacks defined inside it. Problem that Go treat this fields as *[0]byte array type and I can't set it to pointer:

./test.go:16: cannot use _Cgo_ptr(_Cfpvar_fp_cb_func) (type unsafe.Pointer) as type *[0]byte in assignment

Sample of problem code:

package main

/*
void cb_func();
typedef struct cb_s {
    void (*cb_f)();
} cb_s;
*/
import "C"

//export cb_func
func cb_func() {}

func main() {
        var x C.struct_cb_s
        // here I want to set callback cb_f to pointer of cb_func().
        x.cb_f = C.cb_func
}

One possible solution - write a C setter, something like this:

void cb_set(cb_s *s) {
        s->cb_f = &cb_func;
}

but it looks ugly: I can't pass cb_func as argument to setter (already tried cb_set(cb_s *s, void(*func)()), but got the same error about *[0]byte) and have many similar callbacks, so need to write setter for each pair of callback - callback function.

Any other solutions?

Upvotes: 4

Views: 1286

Answers (1)

Gordon Childs
Gordon Childs

Reputation: 36084

That's exactly how you do it, and yes, it is ugly. Don't forget to add the extern void cb_func(void); to your c code.

I ended up with this:

/*
 typedef struct {
     void (*cb_f)();
 } cb_s;

 extern void cb_func(void);

 static void cb_set(cb_s *s) {
     s->cb_f = &cb_func;
 }
 */
import "C"

//export cb_func
func cb_func() {}

func main() {
    var x C.cb_s
    // here I want to set callback cb_f to pointer of cb_func().
    C.cb_set(&x)
}

Upvotes: 4

Related Questions