Universall Asked:2022-08-19 06:40:31 +0800 CST2022-08-19 06:40:31 +0800 CST 2022-08-19 06:40:31 +0800 CST 蟒蛇+通过c去 772 最近我对结合 python 和 go 产生了兴趣(例如,加快一些任务)。我找到了几个关于这个主题的网站,但事实证明你需要将它们结合起来c。我寻求帮助:向不知道c在哪里做的人解释ctrl+ c,ctrl+v以便从 python 调用用 go 编写的函数并给出结果。 PS:网站:1、2 python c 1 个回答 Voted Best Answer eri 2022-08-19T08:18:20+08:002022-08-19T08:18:20+08:00 功能被打包main。最小 sum.go 看起来像这样: package main import "C" //export Sum func Sum(a, b int) int { return a + b } func main() {} //export Sum该行是必需的,没有它 python 将无法通过 si 看到该函数。 这样编译: go build -o sum.so -buildmode=c-shared sum.go 输出为 sum.so 和 sum.h。有关变量类型,请参见 sum.h。 对于类型,需要更多细节。该函数如extern GoInt Sum(GoInt a, GoInt b); GoInt上面的定义所示typedef GoInt64 GoInt;,GoInt64已定义为 C 类型long long,在 python 中将 via 转换ctypes.c_longlong为 python int。在这个例子中,没有必要在 python 中指定类型,但是如果你需要传递一些复杂的东西,你将需要它。 在 python 中,库是通过 ctypes 加载的: import ctypes lib = ctypes.cdll.LoadLibrary("./sum.so") lib.Sum.argtypes = [ctypes.c_longlong, ctypes.c_longlong] print(lib.Sum(1,3)) 使用字符串 通过 c 字符 在 Go 中将字符串转换为 C.char //export Echo func Echo(s *C.char) *C.char { return C.CString( strings.ToUpper( C.GoString( s ) ) ) } 在python中: lib.Echo.argtypes = [ctypes.c_char_p] lib.Echo.restype = ctypes.c_char_p print(lib.Echo('hello'.encode()).decode()) 但是在这里我们必须小心,因为通过指针发出的结果不会释放内存。删除指针时,需要检查 Python 是否释放它。 通过 GoString 如果你导出一个函数,func Echo(s string) string {return strings.ToUpper(s) }那么这可能会导致 Go 垃圾收集器出现问题,并且在调用时它会因错误而崩溃panic: runtime error: cgo result has Go pointer 但是传入的字符串可以像这样从python传递 class GoString(ctypes.Structure): "typedef struct { const char *p; ptrdiff_t n; } _GoString_;" def __init__(self, s): super().__init__(s.encode(), len(s)) def __str__(self): return self.p.decode() _fields_ = [("p", ctypes.c_char_p), ("n", ctypes.c_size_t)] lib.Echo.argtypes = [GoString] lib.Echo(GoString('hello'))
功能被打包
main
。最小 sum.go 看起来像这样://export Sum
该行是必需的,没有它 python 将无法通过 si 看到该函数。这样编译:
输出为 sum.so 和 sum.h。有关变量类型,请参见 sum.h。
对于类型,需要更多细节。该函数如
extern GoInt Sum(GoInt a, GoInt b);
GoInt
上面的定义所示typedef GoInt64 GoInt;
,GoInt64
已定义为 C 类型long long
,在 python 中将 via 转换ctypes.c_longlong
为 pythonint
。在这个例子中,没有必要在 python 中指定类型,但是如果你需要传递一些复杂的东西,你将需要它。在 python 中,库是通过 ctypes 加载的:
使用字符串
通过 c 字符
在 Go 中将字符串转换为 C.char
在python中:
但是在这里我们必须小心,因为通过指针发出的结果不会释放内存。删除指针时,需要检查 Python 是否释放它。
通过 GoString
如果你导出一个函数,
func Echo(s string) string {return strings.ToUpper(s) }
那么这可能会导致 Go 垃圾收集器出现问题,并且在调用时它会因错误而崩溃panic: runtime error: cgo result has Go pointer
但是传入的字符串可以像这样从python传递