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
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()