Cgo: 无法在Go中设置C结构中的回调函数。

huangapple go评论82阅读模式
英文:

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

问题

我有一个在C库中定义了一些回调函数的结构体。问题是Go将这些字段视为*[0]byte数组类型,我无法将其设置为指针:

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

问题代码示例:

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
        // 在这里,我想将回调函数cb_f设置为cb_func()的指针。
        x.cb_f = C.cb_func
}

一个可能的解决方案是编写一个C的setter函数,类似于这样:

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

但这看起来很丑陋:我无法将cb_func作为参数传递给setter函数(已经尝试过cb_set(cb_s *s, void(*func)()),但得到了关于*[0]byte的相同错误),而且有很多类似的回调函数,因此需要为每对回调函数编写一个setter函数。

还有其他解决方案吗?

英文:

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?

答案1

得分: 4

这是翻译好的内容:

这就是你要做的,是的,它很丑。不要忘记在你的C代码中添加extern void cb_func(void);

我最终得到了这个:

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

extern void cb_func();

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
    // 在这里,我想将回调cb_f设置为cb_func()的指针。
    C.cb_set(&x)
}
英文:

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)
}

huangapple
  • 本文由 发表于 2015年10月5日 19:29:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/32947511.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定