zoukankan      html  css  js  c++  java
  • 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中调用测试函数即可测试。

  • 相关阅读:
    python—打开图像文件报错
    CTFshow萌新赛-萌新福利
    微信小程序bug
    微信小程序
    架构
    命令行
    MyBatis
    avalon
    并发测试工具
    less
  • 原文地址:https://www.cnblogs.com/Kingram/p/12359624.html
Copyright © 2011-2022 走看看