Python调用Go语言编译的动态链接库-Python和Go语言混编

1 动态链接库(dll,so文件)

Linux下的动态库以.so 结尾

Windows下的动态库以.dll结尾

具体区别不展开讨论,详情自行百度

2 Go语言打包成动态链接库文件(dll,so)

2.1 windows下

golang 编译 dll 过程中需要用到 gcc,所以先安装 MinGW。

windows 64 位系统应下载地址为: https://sourceforge.net/projects/mingw-w64/

下载后运行 mingw-w64-install.exe,完成 MingGW 的安装

详细过程及解释,参照文章:【window下MinGW-w64的安装:https://zhuanlan.zhihu.com/p/355510947】

2.2 mac,Linux下

自带gcc,无需任何安装

2.3 编写Go代码

package main

import "C"  //必须引入C库

import "fmt"

//加入下面注释代码,表示导出,可以被python调用

//export PrintDll
func PrintDll() {
	fmt.Println("我来自dll")
}

//
//export Sum
func Sum(a int, b int) int {
	return a + b
}



func main() {
	//必须加一个main函数,作为CGO编译的入口,无具体实现代码
}

**注意: **

1 注释 //export PrintBye 和 //export Sum 在编译 动态库(dll ,so)的时候是必须的,说明了 动态库 需要输出的函数。注释和下面的函数名之间不能有空行。
2 main函数必须写,没有执行代码,作为CGO编译的入口

3 必须引入C库(import "C")

2.4 编译成动态库

2.4.1 编译成so库

go build -buildmode=c-shared -o s1.so s1.go

2.4.2 编译成dll库

go build -buildmode=c-shared -o s1.so s1.go

注意:

1 -o表示输出,s1.so 表示编译成so文件的名字,s1.go表示编译哪个go文件

2 "-s -w" 选项用于减小生成动态链接库的体积,-s 是压缩,-w 是去掉调试信息

go build -ldflags "-s -w" -o main.dll -buildmode=c-shared s1.go

image-20210308180624186

3 编译模式buildmode

模式 说明
archive 编译成二进制文件。一般是静态库文件。 xx.a
c-archive 编译成C归档文件。C可调用的静态库。xx.a。注意要编译成此类文件需要import C 并且要外部调用的函数要使用 “//export 函数名” 的方式在函数上方注释。否则函数默认不会被导出。
c-shared 编译成C共享库。同样需要 import “C” 和在函数上方注释 // export xxx
default 对于有main包的直接编译成可执行文件。没有main包的,编译成.a文件
exe 编译成window可执行程序
plugin 将main包和依赖的包一起编译成go plugin。非main包忽略。【类似C的共享库或静态库。插件式开发使用

3 使用python语言来调用

from ctypes import cdll

lib = cdll.LoadLibrary('./s1.so')

# 调用go语言的Sum
result = lib.Sum(100, 200)
print(result)

# 调用go语言的PrintDll
lib.PrintDll()
posted @ 2022-04-29 18:11  刘清政  阅读(507)  评论(0编辑  收藏  举报