Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Numpy Ctypes:分段错误。通过指针传递数组_Python_Arrays_Numpy_Ctypes - Fatal编程技术网

Python Numpy Ctypes:分段错误。通过指针传递数组

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

我试图创建一个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 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一些参数是type
c_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