Golang生成Python动态链接库(python调用Go代码)

7 篇文章 0 订阅
1 篇文章 0 订阅

Golang生成Python动态链接库(python调用Go代码)

前言

我们可以使用Go生成Python的动态链接库,这样就可以在Python中调用Go代码了,会极大的简化代码量。目前我用Go做了一个与匹配命令有关的一个函数,需要给我工作中别的使用python的小伙伴提供一个可在python直接调用的程序,python目前没有办法直接调用go的代码,需要先利用cgo将go的代码先转换一下,才能在python中调用。第一次做这个,跌跌撞撞遇到很多问题,不论是安装C的编译器还是转换数据类型等等等等(我感觉我遇上了所能遇见的各种问题…我做了很多个小demo最终一步步找到问题并解决),但是最终在python中能够调用go代码的那一刻,我露出了慈祥而又满足而又欣慰而又愉悦而又诡异的笑容😀。

使用环境介绍

  • OS:window10
  • Go:1.15.3
  • python:3.9

处理过程

  1. 在自己需要导出的函数上方加上// export 函数名,注意这行注释一定要加上(此外要注意要有main函数,不管main函数上是否有内容,此处我的main函数是空的~想直接在python中写调用)。
    如图所示:
    在这里插入图片描述

  2. 除了自己的程序需要的包以外,还需要导入import "C"包,因为在调用过程中需要用C来做一个媒介。如图所示:
    在这里插入图片描述

  3. 如果是Windows系统,需要安装MingW64----windows版本的c/c++编译器(如果已经安装了可以跳过此步骤,不确定是否安装的话可以使用gcc -v在命令行中查看是否安装成功)。
    下载链接(离线版)https://sourceforge.net/projects/mingw-w64/files/latest/download
    官网地址为
    https://sourceforge.net/projects/mingw-w64/files/mingw-w64/
    还可以点击我的网盘链接下载:https://pan.baidu.com/s/19zOjXVtmpSZffdZAQm9xLQ,提取码:5bnl
    可能由于我自身对MingW64的了解不太多,这个MingW64我在官网下载的时候,自己配置时总是不太全,有同样困扰的小伙伴可以直接下载我网盘提供的安装包下载安装好,按我的步骤做就可以直接用了,我下载的是离线的(注意我的我网盘里的安装包仅适用于windows64位),解压后放到一个合适的位置,接下来就是设置环境变量:右击“我的电脑”—“属性”—“高级系统设置”—“环境变量”—选中“Path”—“系统变量”下的“编辑”:
    在这里插入图片描述
    接着点击“新建”:将bin目录路径放进去,我的路径在:D:\MinGW\mingw64\bin
    在这里插入图片描述
    在cmd中输入gcc -v,有返回的版本结果信息等即可。
    在这里插入图片描述

  4. 然后回到刚才的地方,由于此处我用的是Windows,将go文件编译成dll即可,如果是Linux就编译成so(但事实上我用的windows转换成.so文件也依旧可以使用hiahia~)。语法格式为(在Terminal输入即可):

go build -buildmode=c-shared -o dll文件或者so文件 go源文件

我的执行结果为:
在这里插入图片描述
目前没有报错,继续往下~
就开始了我坎坷的python调用go代码之旅!!!
我在python中写了简单的调用代码:

#!/user/bin/env python3
# -*- coding: utf-8 -*-
import ctypes

lib = ctypes.CDLL('./matchCommand.so')
str = lib.matchCommand("Linux", "factor --version")
print(str)

发现可以进入我的go文件,但是无法进入我的方法,我在网上看到很多文章都说的是go与cgo数据类型不同的问题~(我做了几个简单的小的demo,验证了确实是数据类型的问题… …)需要在go代码中先把数据类型进行转换,于是,我又开始研究官方文档了(此处省略一些很傻的坑…)看到官方文档给出了一些原始的C兼容数据类型(下图),我看见自己的go代码中传入的参数与返回值都是字符串类型,Python是利用ctypes来跟so模块进行交互,其中存在着一个代码的翻译过程,包括数据类型的翻译,如果需要传参获取接收返回值,需要在golang中将参数按照下表对应,定义成C语言的数据类型。
在这里插入图片描述
5. 我对自己最初的代码进行了如下调整:

  • 对传入的参数进行了类型的转换
    在这里插入图片描述
  • 对返回值进行了类型转换:
    在这里插入图片描述
    注意:内部的数据类型不需要做任何改变,只需要更改传入的参数和返回值的类型即可!!我自己的方法中有很多数据类型,包括字节数组、字符串、一些切片等等。。我都转过,后来发现根本不用!!(还是我理解的不够深入…我悔过)
  1. 此时在python中,也不能简单的直接调用了,需要用对应的数据类型进行转换:
#!/user/bin/env python3
# -*- coding: utf-8 -*-
import ctypes
matchCommand = ctypes.CDLL("./matchCommand.so").matchCommand
# 显式声明参数和返回值的期望类型
matchCommand.argtypes = [ctypes.c_char_p, ctypes.c_char_p]
matchCommand.restype = ctypes.c_char_p
# 这个地方在前面加b,是代表bytes
matchCommand(b"linux", b"yum remove")

至此,执行python文件之后,就成功了。整个过程我尽量进行了详细的回忆,如果有不准确的地方,欢迎指正(#^.^#)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值