为了在C/C++ 程序中调用Go 程序, 编写了go的程序库,那么在库函数中如何调用C 语言的回调函数呢?我们尝试一下。
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef void (*callback)(void *,int);
extern void c_callback (void *,int);
extern callback _cb;
*/
import "C"
import (
// "encoding/json"
"unsafe"
)
func funccallback(gostring string,goint int) {
var cmsg *C.char = C.CString(gostring)
var ivalue C.int = C.int(len(gostring))
defer C.free(unsafe.Pointer(cmsg))
C.c_callback(unsafe.Pointer(cmsg),ivalue)
}
//export register_callback
func register_callback(p C.callback) {
C._cb = p;
return
}
//export test_callback
func test_callback() {
funccallback("hello,this is func callback.",123)
}
func main() {
}
对C开放了两个函数 register_callback 和 test_callback
go库函数通过一个桥接函数回调 C程序中的函数
package main
/*
#include <stdio.h>
typedef void (*callback)(void *,int);
callback _cb;
void c_callback(void* p,int i)
{
_cb(p,i);
}
*/
import "C"
编译go 程序库
go build -o libcallback.so -buildmode=c-shared libcallback.go bridge.go
有一点没有搞明白,为什么不能将bridge.go 的桥接函数放到libcallback.go 中,而需要独立出来一个文件bridge.go?
C 主程序
#include <stdio.h>
#include "libcallback.h"
void gocallback(void* s,int len) {
printf("raw data: %s\n",(char *)s);
}
int main() {
// 注册回调
register_callback(gocallback);
// 测试回调
test_callback();
}
编译
gcc -o testcallback main.c ./libcallback.so
运行结果
$ ./testcallback
raw data: hello,this is func callback.
程序的调用关系
灰色为Go 的函数,红色为C语言的函数,Call _cb 存放回调函数的指针。