工作需要go和c混编,当go调用有回调函数的C语言函数的时候,不能直接将go中定义的函数作为参数传递给C语言函数。
遵循以下步骤:
- 使用go语言定义一个回调函数,通过注释 “//export 函数名” 将函数导出
- 在import “C” 上通过注释以C语言的格式对Go语言定义的回调函数进行声明
- 在import “C” 上通过注释,定义一个连接Go语言和C语言的函数(这里我称作桥接函数了),在这个桥接函数中调用使用Go语言定义的回调函数。
- 将桥接函数做为回调函数传递给C语言的函数
代码如下:
package main
/*
#include<stdio.h>
#include <unistd.h>
typedef int (*callback_func)(int);
__attribute__((weak)) // 解决 multiple definition
int run_callback(callback_func cb, int x) {
if (cb != NULL) {
int result = cb(x);
printf("Callback result: %d\n", result);
fflush(stdout);
return result;
} else {
printf("No callback provided.\n");
fflush(stdout);
return -1; // 或其他适合的错误值
}
}
## 步骤2
// 以c语言的方式声明外部的Go函数
extern int goCallback(int x);
## 步骤3
// 桥接函数
__attribute__((weak))
int bridge_goCallback(int x) {
return goCallback(x); // 调用真正的Go语言函数,并返回结果
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func main() {
## 步骤4
// 将桥接函数作为参数传递给C语言函数
cb := C.callback_func(unsafe.Pointer(C.bridge_goCallback))
res := C.run_callback(cb, 5)
fmt.Printf("======> %v \n", res)
}
## 步骤1
//export goCallback
func goCallback(x C.int) C.int {
fmt.Printf("当前数值: %d", x)
return x * 2
}