• go调用so库


    来源:微信公众号「编程学习基地」

    go调用so库

    生成so库

    load_so.h

    #ifndef _LOAD_SO_H
    #define _LOAD_SO_H
    
    int do_test_so_func(int a,int b);
    
    #endif  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    load_so.c

    #include "load_so.h"
    
    int do_test_so_func(int a,int b)
    {
        return a + b;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    生成so文件

    gcc -fPIC -shared -o libload_so.so load_so.c
    
    • 1
    调用so库

    创建go项目hello

    mkdir cgoTest
    
    • 1

    创建main.go

    touch main.go
    
    • 1

    内容如下

    package main
    
    /*
    #cgo CFLAGS: -I ./include    
    #cgo LDFLAGS: -L /home/dengzr/cgoTest/lib -lload_so
    #include "include/load_so.h"
    */
    import "C"
    import (
    	"fmt"
    )
    
    func main() {
    	val := C.do_test_so_func(1,1)
    	fmt.Printf("num1: %v\n", val)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    将so库及头文件导入cgoTest目录结构如下

    ├── include
    │   ├── load_so.c
    │   └── load_so.h
    ├── lib
    │   └── libload_so.so
    └── main.go
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    初始化go项目环境

    [root@zs3-2 cgoTest]# go mod init cgoTest
    
    • 1

    编译go程序

    [root@zs3-2 cgoTest]# go build cgoTest
    
    • 1

    导入so库环境变量

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/dengzr/cgoTest/lib/
    
    • 1

    运行测试用例

    [root@zs3-2 cgoTest]# ./cgoTest
    num1: 2
    
    • 1
    • 2
    回调函数如何处理

    .h

    #ifndef _LOAD_SO_H
    #define _LOAD_SO_H
    
    typedef void (*Callback)(int);
    
    void callCFunction(Callback fun);
    
    int do_test_so_func(int a,int b);
    
    #endif  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    .c

    #include "load_so.h"
    int do_test_so_func(int a,int b)
    {
        return a + b;
    }
    
    void callCFunction(Callback fun)
    {
        fun(10);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    .go

    package main
    
    /*
    #cgo CFLAGS: -I ./include    
    #cgo LDFLAGS: -L /home/dengzr/fmp4/cgoTest/lib -lload_so -lbsr-fmp4-mux
    #include "include/load_so.h"
    #include "include/fmp4MuxAPI.h"
    
    
    // 导出Go函数为C函数
    extern void goCallback(int);
    */
    import "C"
    import (
    	"fmt"
    	"os"
    	"io"
    	"bytes"
    	"encoding/binary"
    )
    // Go回调函数
    //export goCallback
    func goCallback(value C.int) {
        fmt.Println("Go callback called with value:", int(value))
    }
    func main() {
    	val := C.do_test_so_func(1,1)
    	fmt.Printf("num1: %v\n", val)
    
    	// 在Go代码中调用C回调函数
    	fun := (C.Callback)(C.goCallback)
    	C.callCFunction(fun)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    注意,go回调函数前必须导入 export goCallback,否则报错

    /home/dengzr/go/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
    /tmp/go-link-267202374/go.o:(.data+0x8): undefined reference to `goCallback'
    collect2: error: ld returned 1 exit status
    
    • 1
    • 2
    • 3

    必须声明extern void goCallback(int);否则未定义C.goCallback

  • 相关阅读:
    Secure Boot(安全启动)
    java面试题含答案
    java计算机毕业设计vue架构云餐厅美食订餐系统MyBatis+系统+LW文档+源码+调试部署
    #1全职独立开发两周总结
    面试学习总结
    【windows】如何全部关闭360安全的弹出guang告?(已解决)
    uniapp插件uViewplus的使用(涉及TS下的问题)
    OpenCV15-图像边缘检测:Sobel、Scharr、Laplace、Canny
    企业使用人工智能创建营销内容的8种实践
    CUDA核函数,如何设置grid和block即不超过大小又能够遍历整个volume
  • 原文地址:https://blog.csdn.net/qq_44519484/article/details/132967803