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

标签 c go binding cgo

假设我有一个包含如下代码的 C 库:

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

我想为此函数编写 go 绑定(bind)并传递任意 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))
}

有没有办法正确绑定(bind) C 库?

最佳答案

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

关于c - 将 Go 函数作为回调传递给 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37703779/

相关文章:

c - 我应该在 MSVC - C 上使用安全版本的 POSIX 函数吗

c - 为什么这段代码会有输出?

c - 快速读取大于c中内存的文件

mysql - 如何使用Golang将值插入decimal(65,0)并从数据库中检索它们?

c# - 将 View 模型中的 ObservableCollection 绑定(bind)到列表框

c# - 以编程方式绑定(bind) ItemsSource

c - C 中的内联汇编。错误的翻译

goroutine 值返回顺序

带缓冲区和超时的 Go writer

java - Guice:在没有 @Singleton 或以其他方式修改实现的情况下配置单例