如何使用 ctypes 将数组从 Go [lang] 返回到 Python?

我正在尝试编写一些在 GoLang 中创建数组的代码,并将其返回给 python 脚本 ctypes(和一些 numpy)。到目前为止我所得到的不起作用,我不明白为什么......我将不胜感激任何帮助!


我的 Go 代码是这样的:


func Function(physics_stuff... float64,  N int ) []float64{

    result := make([]float64, N)

    for i:= 0; i< N; i++{

        result[i] =  blah....

    }

    return result;

}

我目前正在尝试使用以下方法将此功能导入 python:


from ctypes import c_double, cdll, c_int

from numpy.ctypeslib import ndpointer


lib = cdll.LoadLibrary("./go/library.so")

lib.Function.argtypes = [c_double]*6 + [c_int]


def lovely_python_function(stuff..., N):

    lib.Function.restype = ndpointer(dtype = c_double, shape = (N,))

    return lib.Function(stuff..., N)

这个 python 函数永远不会返回。来自同一个库的其他函数工作得很好,但它们都返回一个 float64(python 中的 c_double)。


鸿蒙传说
浏览 103回答 1
1回答

有只小跳蛙

在您的代码中restype期待_ndtpr类型,请参阅:lib.Function.restype = ndpointer(dtype = c_double, shape = (N,))在 numpy 文档中也可以看到:def ndpointer(dtype=无,ndim=无,形状=无,标志=无)[其他文本]退货klass : ndpointer 类型对象一个类型对象,它是一个_ndtpr包含 dtype、ndim、shape 和 flags 信息的实例。[其他文本]这种方式lib.Function.restype就是指针类型,在Golang中挪用的类型一定是unsafe.Pointer。但是你想要一个需要作为指针传递的切片:func Function(s0, s1, s2 float64, N int) unsafe.Pointer {    result := make([]float64, N)    for i := 0; i < N; i++ {        result[i] = (s0 + s1 + s2)    }    return unsafe.Pointer(&result)//<-- pointer of result}这会导致在Go 和 C 之间传递指针的规则中出现问题。调用返回后,C 代码可能不会保留 Go 指针的副本。所以必须转unsafe.Pointer成uintptrgolang类型。func Function(s0, s1, s2 float64, N int) uintptr {    result := make([]float64, N)    for i := 0; i < N; i++ {        result[i] = (s0 + s1 + s2)    }    return uintptr(unsafe.Pointer(&result[0]))//<-- note: result[0]}这样你就可以正常工作了!注意: C 中 slice 的结构由 表示typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;,但 C 只需要数据,因为这只是需要结果void *data(第一个字段,或字段[0])。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go