Python Numpy Ctypes:分段错误。通过指针传递数组
我试图创建一个C函数的python接口,其结构如下:(可以找到完整的代码) 但是,当我尝试运行代码时,我得到以下错误,这似乎与第一个参数的类型转换有关:Python Numpy Ctypes:分段错误。通过指针传递数组,python,arrays,numpy,ctypes,Python,Arrays,Numpy,Ctypes,我试图创建一个C函数的python接口,其结构如下:(可以找到完整的代码) 但是,当我尝试运行代码时,我得到以下错误,这似乎与第一个参数的类型转换有关: x =np.array([[1.,0.,0.],[1.,1.,0.],[2.,0.5,np.sqrt(.75)]]) sf.getPiTyped(x,1,2,1.5) ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't know how to conver
x =np.array([[1.,0.,0.],[1.,1.,0.],[2.,0.5,np.sqrt(.75)]])
sf.getPiTyped(x,1,2,1.5)
ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't know how to convert parameter 1
但是我仍然得到seg错误上面Warren强调了错误,int参数必须通过引用传递。还要注意,数组必须是连续的。以下是最终代码:
import numpy as np
import ctypes as ct
# Load the library as _libspfc.
_libspfc = np.ctypeslib.load_library('../src/libspatialfuncs', '.')
def getPiTyped(posmat,typeA=-1,typeB=-1,r=np.array([1.]),rLow=None):
"""
Python equivalent to get_pi_typed.
posmat: a matrix with columns type, x and y
typeA: the "from" type that we are interested in, -1 is wildcard
typeB: the "to" type that we are interested i, -1 is wildcard
r: the series of spatial distances wer are interested in
rLow: the low end of each range....0 by default
"""
#prepare inputs
# argument 1 to 3: make a copy, so the matrix is C contiguous (already included in astype)
ty=posmat[:,0].astype(np.int32)
x=posmat[:,1].copy()
y=posmat[:,2].copy()
n = ct.c_int(posmat.shape[0])
typeA = ct.c_int(typeA)
typeB = ct.c_int(typeB)
if not isinstance(r, np.ndarray): #if it is not a 1D numpy array (for ex a scalar or a list), bring it into that shape
r=np.array(r)
r=r.reshape((-1))
if rLow is None:
rLow = np.zeros_like(r)
if not isinstance(rLow, np.ndarray): #if it is not a 1D numpy array (for ex a scalar or a list), bring it into that shape
rLow=np.array(rLow)
rLow=rLow.reshape((-1))
rLen=ct.c_int(r.shape[0])
ind=np.arange(1,r.shape[0]+1,dtype=np.int32)
#prepare output array
rc = np.empty_like(r, dtype=np.double)
_libspfc.get_pi_typed(ty,\
x,\
y,\
ct.byref(n),\
ct.byref(typeA),\
ct.byref(typeB),\
rLow,\
r,\
ct.byref(rLen),\
ind,\
rc)
return rc
有帮助吗?如果我没记错的话,ctypes数组就是指针器。您是否已尝试将数组作为
posmat[:,0].ctypes.data
传递给c函数?只是尝试将.ctypes.data
添加到所有numpy数组参数中。ArgumentError现在消失了,但是我得到了一个SegmentationFault。那么,这可能是朝着正确方向迈出的一步。尝试转置x
并传递行而不是列。c函数可能需要连续数组。顺便说一句,请注意,我以前没有这样做,只是在黑暗中猜测:)谢谢你的帮助!我试图使数组列连续posmat=np.ascontiguousarray(np.asfortranarray(posmat))
,但我仍然得到seg错误。您已经告诉ctypes一些参数是typec_int
,但c函数的实际参数是指向int的指针。这肯定会触发一个故障。
x =np.array([[1.,0.,0.],[1.,1.,0.],[2.,0.5,np.sqrt(.75)]])
sf.getPiTyped(x,1,2,1.5)
ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't know how to convert parameter 1
posmat=np.ascontiguousarray(np.asfortranarray(posmat))
import numpy as np
import ctypes as ct
# Load the library as _libspfc.
_libspfc = np.ctypeslib.load_library('../src/libspatialfuncs', '.')
def getPiTyped(posmat,typeA=-1,typeB=-1,r=np.array([1.]),rLow=None):
"""
Python equivalent to get_pi_typed.
posmat: a matrix with columns type, x and y
typeA: the "from" type that we are interested in, -1 is wildcard
typeB: the "to" type that we are interested i, -1 is wildcard
r: the series of spatial distances wer are interested in
rLow: the low end of each range....0 by default
"""
#prepare inputs
# argument 1 to 3: make a copy, so the matrix is C contiguous (already included in astype)
ty=posmat[:,0].astype(np.int32)
x=posmat[:,1].copy()
y=posmat[:,2].copy()
n = ct.c_int(posmat.shape[0])
typeA = ct.c_int(typeA)
typeB = ct.c_int(typeB)
if not isinstance(r, np.ndarray): #if it is not a 1D numpy array (for ex a scalar or a list), bring it into that shape
r=np.array(r)
r=r.reshape((-1))
if rLow is None:
rLow = np.zeros_like(r)
if not isinstance(rLow, np.ndarray): #if it is not a 1D numpy array (for ex a scalar or a list), bring it into that shape
rLow=np.array(rLow)
rLow=rLow.reshape((-1))
rLen=ct.c_int(r.shape[0])
ind=np.arange(1,r.shape[0]+1,dtype=np.int32)
#prepare output array
rc = np.empty_like(r, dtype=np.double)
_libspfc.get_pi_typed(ty,\
x,\
y,\
ct.byref(n),\
ct.byref(typeA),\
ct.byref(typeB),\
rLow,\
r,\
ct.byref(rLen),\
ind,\
rc)
return rc