为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
鸿蒙传说 2023-03-21 14:44:51
我正在尝试编写一些在 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_intfrom numpy.ctypeslib import ndpointerlib = 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)。
查看完整描述

1 回答

?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

在您的代码中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 之间传递指针的规则中出现问题。

  1. 调用返回后,C 代码可能不会保留 Go 指针的副本。

所以必须转unsafe.Pointeruintptrgolang类型。


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])。


查看完整回答
反对 回复 2023-03-21
  • 1 回答
  • 0 关注
  • 102 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信