将Go函数传递给C作为回调

时间:2016-06-08 13:23:14

标签: c go binding cgo

假设我有一个C库,代码如下:

typedef int (callback_t)(int);
void register_callback(callback_t cb);

我想为此函数编写go绑定并传递任意go回调。

我找到了一个很好的答案here。然而,这是一个利用回调接受void *这一事实的技巧,Go通过该函数将函数指针传递给C并将其接收回来。但是,由于没有用户void *

,因此无法在我的示例中应用此功能

我能做的最好的事情是:

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

这仅适用于单个register_callback(因为全局变量),但C库可以注册许多回调并全部调用它们。

我希望实现类似这样的东西,但这不会编译(抛开clojure,即使签名相同也无法将go函数转换为c函数):

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

有没有办法正确绑定C库?

1 个答案:

答案 0 :(得分:0)

如果没有返回值(void函数),你可以创建一个回调数组并让桥接器迭代回调数组。