背景
就突发奇想,Go的效率相对来说高一些,那我们可不可以用Go来给python写关键处理库呢
查了下,还真可以实现,只是障碍比较多,而且使用起来也比较麻烦,但是也还是能实现的
解决
用 Go 编写 Python 库可以通过 Cgo 或 C共享库 的方式实现。
Go 代码可以被编译为 C 兼容的共享库(.so 或 .dll),然后通过 Python 的 ctypes 或 cffi 模块调用。
go代码
package main
import "C"
import "fmt"
//export Add
func Add(a, b int) int {
return a + b
}
//export Greet
func Greet(name *C.char) *C.char {
msg := fmt.Sprintf("Hello, %s!", C.GoString(name))
return C.CString(msg)
}
func main() {} // 必须有一个 main 函数
注意点:
- 一定要使用
//export
将函数导出,否则,是无法被编译到库中的,双斜杠后面一定不能有空格- 因为 Go 的字符串类型(string)与 C 的字符串类型不直接兼容,所以在 Go 和 C 之间传递字符串时,需要使用 C 的字符串类型(*C.char)这一点很关键
- 必须有一个
main
函数
编译
使用以下命令将 Go 代码编译为 C 共享库:
Linux/MacOS:
go build -o mylib.so -buildmode=c-shared .
生成 mylib.so 和 mylib.h 文件。
Windows:
go build -o mylib.dll -buildmode=c-shared .
生成 mylib.dll 和 mylib.h 文件。
python中使用
使用 Python 的 ctypes 模块加载共享库并调用函数。
import ctypes
import os
# 根据不同操作系统加载对应的共享库
if os.name == "nt": # Windows
lib = ctypes.cdll.LoadLibrary("mylib.dll")
else: # Linux/MacOS
lib = ctypes.cdll.LoadLibrary("./mylib.so")
# 定义函数签名 这里需要跟go中的对应
lib.Add.argtypes = (ctypes.c_int, ctypes.c_int)
lib.Add.restype = ctypes.c_int
# 因为是指针,所以是c_char_p
lib.Greet.argtypes = (ctypes.c_char_p,)
lib.Greet.restype = ctypes.c_char_p
# 调用 Go 函数
result = lib.Add(3, 4)
print(f"Add(3, 4) = {result}") # 输出: Add(3, 4) = 7
name = "World".encode("utf-8")
greeting = lib.Greet(name).decode("utf-8")
print(greeting) # 输出: Hello, World!
总结
总的来说,还是能够顺利达到目的
但是实际写下来,发现其实障碍挺多
尤其这个 类型 ,很多都是无法相通的,不相通就没法编译成功
所以,玩玩还行,真掏出来用,还得下点功夫
标签:lib,mylib,python,char,Go,Add,ctypes,GO,共享 From: https://www.cnblogs.com/guangdelw/p/18675556