• Golang编写动态库实现回调函数


    Golang编写动态库实现回调函数

    我们现在要做一个动态库,但是C++实在是比较难,于是就想能不能用更简单的golang来实现,golang也就是最近的版本才支持编译成动态库,在网上也没找到可用的案例,好在我们解决了这个问题,这边写个笔记造福大众。

    main.go

    package main
    /*
    #cgo CFLAGS: -I .
    #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_rsucallback
    func register_rsucallback(p C.rsucallback) {
    	C._cb = p;
    	return
    }
    
    //export test_callback
    func test_callback() {
    	funccallback("hello,this is func callback.",123)
    }
    
    func main() {
    }
    

    bridge.go

    package main
    
    /*
    #include <stdio.h>
    
    typedef void (*callback)(void *,int);
    
    callback _cb;
    
    void c_callback(void* p,int i)
    {
    	_cb(p,i);
    }
    */
    import "C"
    

    这样写完直接调用以下命令即可生成main.dll文件和main.h文件

    winows编译动态库参考我的这篇文章

    go build -o main.dll -buildmode=c-shared main.go bridge.go
    

    然后就是C语言的测试程序调用

    main.c

    #include <stdio.h>
    #include "main.h"
    
    void gocallback(void* s,int len) {
         printf("raw data: %s
    ",s);
    }
    
    int main() {
        // 注册回调
        register_callback(gocallback);
        
        // 测试回调
        test_callback();
    }
    

    把C程序编译一下即可测试。

    有时我们需要在别的包里调用这个回调函数,这时可以做一个工具

    utils包callbackutils.go

    package utils
    
    type funVarType func(string,int)
    
    var FunVar func(string,int)
    
    func SetFuncAddr(a funVarType) {
    	FunVar=a
    }
    
    func Funccallbackutil (gostring string,i int) {
    	FunVar(gostring,i)
    }
    

    在main.go中可以写个init函数做个初始化

    func init() {
    	utils.SetFuncAddr(funccallback)
    }
    

    然后在写一个测试的函数导出

    //export test_callbackutil
    func test_callbackutil() {
    	utils.Funccallbackutil("hello this is func callbackutil test",123)
    }
    

    最后在main.c中调用测试函数即可测试。

  • 相关阅读:
    Day2----Python常用模块
    Day1--Python基础知识
    AES加密
    MOS管基本MOS管基本认识(快速入门)认识(快速入门)
    printf定义宏方便调试
    ESP8266上电透传与手动透传AT指令设置笔记
    三态门与高阻态
    步进电机原理
    关于stm32 MCU申请动态内存malloc的认识
    高低位数据分离的两种方法
  • 原文地址:https://www.cnblogs.com/Kingram/p/12359624.html
Copyright © 2020-2023  润新知