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

如何使用ctypes将数组从Go[lang]返回到Python?,python,numpy,go,ctypes,ffi,Python,Numpy,Go,Ctypes,Ffi,我试图编写一些代码,在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

我试图编写一些代码,在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函数永远不会返回。同一库中的其他函数工作正常,但它们都返回一个float64(python中的c\u double)。

在代码中
restype
需要
\ndtpr
类型,请参阅:

lib.Function.restype = ndpointer(dtype = c_double, shape = (N,))
请参见numpy文档中的:

def ndpointer(dtype=None,ndim=None,shape=None,flags=None)

[其他案文]

返回

klass:ndpointer类型对象

类型对象,它是包含
数据类型、ndim、形状和标志信息

[其他案文]

这样一来,
lib.Function.restype
就是指针类型,Golang中的相应类型必须是
safe.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
}
这样你会工作得很好

注意:C中切片的结构由
typedef struct{void*data;GoInt len;GoInt cap;}GoSlice,但C只需要数据,因为这是只需要结果
void*data
(第一个字段,或字段[0])


PoC:

尝试
lib.Function.restype=c\u double*N
(大小为N的数组)或
lib.Function.restype=ctypes.POINTER(c\u double)#在函数
之外,在函数中
res=lib.Function(stuff…,N);return[res[i]for i in range(N)]
遗憾的是,它仍然没有返回澄清一下,python函数甚至对于
N
的一个小值也没有返回?是的,如果我只将return语句更改为其他语句(看看函数运行需要多长时间),一切正常。祝福你!它起作用了!非常感谢。(顺便说一句,我看你还没有把代码推给销售代表,这是个好主意)
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
}
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]
}