【问题标题】:Cgo: can't set callback in C-struct from GoCgo:无法在 Go 的 C-struct 中设置回调
【发布时间】:2015-10-05 19:54:23
【问题描述】:

我在 C lib 中有一个结构,其中定义了一些回调。 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
        // here I want to set callback cb_f to pointer of cb_func().
        x.cb_f = C.cb_func
}

一种可能的解决方案 - 编写一个 C 设置器,如下所示:

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

但它看起来很难看:我不能将 cb_func 作为参数传递给 setter(已经尝试过 cb_set(cb_s *s, void(*func)()),但在 *[0]byte 上遇到了同样的错误)并且有许多类似的回调,因此需要为每个回调编写 setter一对回调——回调函数。

还有其他解决方案吗?

【问题讨论】:

    标签: go cgo


    【解决方案1】:

    这正是你的做法,是的,它很丑陋。不要忘记将extern void cb_func(void); 添加到您的 c 代码中。

    我最终得到了这个:

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

    【讨论】:

    • 我已经有了与问题中提到的几乎相同的代码,但是将 C 包装器放在单独的 *.c 文件中以消除双重编译。不管怎么说,还是要谢谢你。将等待任何其他解决方案,我希望它存在。
    • 还有其他解决方案吗?
    猜你喜欢
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    • 2021-07-23
    • 2015-09-18
    • 2021-02-20
    • 2017-01-02
    • 1970-01-01
    • 2021-12-22
    相关资源
    最近更新 更多