尝试用GO给python写共享库

背景

就突发奇想,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!

总结

总的来说,还是能够顺利达到目的
但是实际写下来,发现其实障碍挺多
尤其这个 类型 ,很多都是无法相通的,不相通就没法编译成功

所以,玩玩还行,真掏出来用,还得下点功夫

posted @   厚礼蝎  阅读(25)  评论(0编辑  收藏  举报
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
历史上的今天:
2024-01-16 ubuntu部署fail2ban并配置防止暴力破解
点击右上角即可分享
微信分享提示