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

Posted

技术标签:

【中文标题】将 Go 函数作为回调传递给 C【英文标题】:Pass Go function to C as callback 【发布时间】:2016-10-08 19:08:01 【问题描述】:

假设我有一个 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 库?

【问题讨论】:

你读过github.com/golang/go/wiki/cgo吗?那里有很多例子。 @JimB,在那里找不到一个合适的例子,你能指出一个吗? 【参考方案1】:

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

【讨论】:

以上是关于将 Go 函数作为回调传递给 C的主要内容,如果未能解决你的问题,请参考以下文章

将c ++引用的地址传递给指针

Ruby - 将方法作为回调传递给 DLL 库

将非托管方法作为回调传递给托管 C++/CLI 类

如何将 C++ 回调传递给 C 库函数?

C#/C++ 回调作为 NULL 传递

Twisted-将结果传递给多个回调