Go打包动态库,python调用

Published on with 0 views and 0 comments

Balabala

在写AGV调度的时候发现python的并发调度性能不是很高,并且会有很多调度线程挂掉的事件发生,所以想利用Go的高并发去做一些可行的调度,就想到了去写一个go版本的调度控制给py调用,由此,开始搞一个小demo记录一下

Go简单程序编写

安装Go语言

还是老规矩,用了ubuntu18的系统,以ubuntu18为主
先去下一下官网的包,我下的版本是go1.13.4.linux-amd64
下好之后随便解压个位置,比如

tar xf go1.13.4.linux-amd64.tar.gz -C /home/用户名/go

解压到/home/用户名/go文件夹下,需要配置全局变量

sudo vim ~/.bashrc

在最后一行加上两行配置

export GOPATH=/home/用户名/go
export PATH=$GOPATH/bin:$PATH

就不多说了这俩。。
验证一下是否成功

go version

成功的话,返回如下

go version go1.13.4.linux-amd64

最简单程序编写

go程序编写就不多说了,文档也很多,就简单的写个返回字符串函数

package main

import "C"

//export GetName
func GetName() *C.char{
	return C.CString("symoon is so cool")
}

func main(){
}

首先build的镜像需要导入C库,原因是因为字符串类型不互通,需要把返回的字符串转成C string,道理就不多说了。
还有//export这个是必须的,不声明的话此函数无法在动态库中被调用,无法生成相应.h文件
当前代码文件main.go,所以我们直接执行

go build -buildmode=c-shared -o test.so main.go

执行后生成test.so动态库文件,根据不同系统生成不一样这个就不多说了。

Python调用Go动态库

动态库调用

这个balabala就不说了吧。。。

sudo apt install python3

接下来直接写代码吧vim test.py

import ctypes

lib = ctypes.CDLL("./test.so")

msg = lib.GetName

msg.restype = ctypes.c_char_p

msg_b=msg()
print(msg_b.decode("utf-8"))

也非常简单,返回的是字节,转成字符串就可以了,所以在Go里面执行业务也是没问题的,传参也需要转类型balabala...

调用传参

Go编译代码

因为在调用go的动态库时候,我们往往希望向里面传递json数据,然而go的string和c的string是需要转换的,所以,直接贴一下代码吧

package main

import "C"
import (
	"encoding/json"
	_"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

//export Dic
type Dic struct {
	Msg string
	Cookie string
}
//export GetName
func GetName(pyStr *C.char) *C.char{
	fmt.Println(C.GoString(pyStr))
	var s Dic
	err:=json.Unmarshal([]byte(C.GoString(pyStr)),&s)
	if err!=nil{
		fmt.Println(err)
	}
	fmt.Println(s)
	return C.CString(s.Msg)
}

func main(){
}
go build -buildmode=c-shared -o test.so main.go

这里有一点要注意,写好结构体,接取json字符串就行了,然后就,变成go可用的对象了,接下来上python

Python调用代码

这里边也没啥好说的了,就是传递的时候一定要传二进制

import ctypes, json

lib = ctypes.CDLL("./test.so")

dic = {
        "msg": "hello , here is symoon", "cookie":"balabala"
    }

    msg = lib.GetName
    msg.restype = ctypes.c_char_p
    msg_b = msg(json.dumps(dic).encode('utf-8'))

    print(msg_b.decode("utf-8"))

最后运行结果就是hello, here is symoon

------------------------- 走在路上的symoon