[英]How to return an array from Go[lang] to Python using ctypes?
我正在嘗試編寫一些在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)。
在您的代碼中, restype
期望_ndtpr
類型,請參閱:
lib.Function.restype = ndpointer(dtype = c_double, shape = (N,))
在numpy文件中也看到了:
def ndpointer(dtype = None,ndim = None,shape = None,flags = None)
[其他文本]
返回
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指針的副本。
資料來源: https : //github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md
所以你必須將unsafe.Pointer
轉換為uintptr
golang類型。
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中切片的結構由typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
,但C只期望數據,因為這需要結果只有void *data
(第一個字段,或字段[0])。
PoC: https : //github.com/ag-studies/stackoverflow-pointers-ref-in-golang
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.