golang 调用 c的回调函数

  1. golang 调用一个c的so库, 函数RegisterCan

  2. c的回调函数结构如下

typedef void (*CanCallBack)(int canChannel, char * canFrame, int canDataLen,unsigned long long canTime);

int RegisterCan(CanCallBack event);
  1. 要用go的实现CanCallBack回调函数的方法

网上找到相关cgo的说明,不是很懂,还望好心人给与提示

https://golang.org/cmd/cgo/#h...

阅读 11.5k
3 个回答

感谢各位的支持,已经找到解决办法

3个文件, can.go , load_so.c , load_so.h

can.go


/*
#include "load_so.h"
#cgo LDFLAGS: -ldl

*/
import "C"



//export CanProcess
func CanProcess(channel int, canFrame string, canDataLen int, timeOfCan uint64) {
    //TODO 具体回调业务
}

// 供外部调用
func Receive(){
    C.callback()
}

load_so.c

#include "load_so.h"
#include <dlfcn.h>

void CanProcess(int canChannel,char *  canFrame, int canDataLen,unsigned long long canTime);

int DoRegisterCan(CanCallBack event)
{
    void* handle;
    typedef int (*FPTR)(CanCallBack);

    handle = dlopen("./lib/filename.so", 1);
    if(!handle) {
         return -1;
       }
    FPTR fptr = (FPTR)dlsym(handle, "RegisterCan");

    int result = (*fptr)(event);
    return result;
}

int callback()
{
    return DoRegisterCan(CanProcess);
}

load_so.h

typedef void (*CanCallBack)(int canChannel, char * canFrame, int canDataLen,unsigned long long canTime);

int DoRegisterCan(CanCallBack event);

int callback();

说白了,题主需求的场景就是:

  • go语言侧代码调用第三方的C语言库函数,但是库函数要求传入一个函数指针作为回调,然后题主想用cgo实现这个回调

golang官方关于cgo的wiki页有详细的关于题主询问场景下的解决方法介绍。

主要是要做几件事情:

  1. 用cgo实现这个回调函数的本体。比如实现一个类似下面这样的cgo函数,并将其导出

    func CanCallBack(canChannel  int, canFrame C.String, canDataLen int, 
    canTime uint64) {
        //...函数具体实现
    }

    以上伪代码是随手写的,主要是参数类型不知道是否合适,特别是那个char 的参数需要根据实际情况来决定在cgo中定义成什么。*

  2. 在注释部分用C语言语法实现一个gateway function(gateway function的介绍可参见上文给出的链接,gateway function的签名必须和函数指针一致)。在这个gateway function中通过上述回调函数的导出签名来调用上述回调函数

  3. 在你想调用第三方库函数代码的cgo代码中调用这个第三方函数,传参时把上述gateway function的函数名传入

总得来说就是以上三件事,但是具体写代码时还有一些细节需要注意的,我之前写过一篇博客有提到这些注意点,感兴趣的话,题主可以参考一下:

C语言程序通过函数指针调用Go函数的方法

我写的这篇博客讨论的场景和题主期待的场景略有不同,望注意. 不过这里面存在的坑是共通的,比如说必须定义为main包之类的

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题