GO 和C 的相互调用(2)-go动态库的C语言回调函数

为了在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 存放回调函数的指针。

猜你喜欢

转载自blog.csdn.net/yaojiawan/article/details/108995888
go