I am trying to create a python interface to a C function with the following structure: (Full code can be found here)
void get_pi_typed (int *type,
           double *x,
           double *y,
           int *len,
           int *typeA,
           int *typeB,
           double *r_low,
           double *r,
           int *len_r,
           int *inds,
           double *rc) {
\*DETAILS LEFT OUT
for (i=0;i<*len_r;i++) {
    \*DETAILS LEFT OUT
    rc[i] = (double)num_cnt/denom_cnt;
    }
}
My Python code looks like this:
import numpy as np
import ctypes as ct
# must be a double array, with single dimension that is contiguous
array_1d_int = np.ctypeslib.ndpointer(dtype=np.int32, ndim=1, flags='CONTIGUOUS')
array_1d_double = np.ctypeslib.ndpointer(dtype=np.double, ndim=1, flags='CONTIGUOUS')
# Load the library as _libspfc.
_libspfc = np.ctypeslib.load_library('../src/libspatialfuncs', '.')
_libspfc.get_pi_typed.argtypes = [array_1d_int,\
                                    array_1d_double,\
                                    array_1d_double,\
                                    ct.c_int,\
                                    ct.c_int,\
                                    ct.c_int,\
                                    array_1d_double,\
                                    array_1d_double,\
                                    ct.c_int,\
                                    ct.c_int,\
                                    array_1d_double,\
                                    ]
_libspfc.get_pi_typed.restype  = None
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
    """
    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))
    #prepare output array
    rc = np.empty_like(r, dtype=np.double)
    _libspfc.get_theta_typed(posmat[:,0],posmat[:,1],posmat[:,2],posmat.shape[0],typeA,typeB,rLow,r,r.shape[0],np.arange(1,r.shape[0]+1),rc)
    return rc
However, when I try to run the code I get the following error, which seems to be related to the type conversion of the 1st parameter:
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
I tried many variations of argtypes, as well as to convert posmat[:,0] to int or int32 via .astype, however I always get the same error. What am I doing wrong?
EDIT:
According to the 1st comment below I added .ctypes.data to all array input arguments. The ArgumentError is now gone. However I get a Segmentation Fault, very difficult to investigate because python crashes
EDIT2: I tried to make the array column-contiguous
posmat=np.ascontiguousarray(np.asfortranarray(posmat))
but I still get the seg fault