python: sigsegv when using ctypes on cygwin
Question: I am trying to compile and use a c library in python using ctypes module. The
library is strangely working fine on Linux machine but throwing SIGSEGV on
Cygwin64.

    
    
    import ctypes
    import numpy as np
    import pdb
    
    xbry = np.array([0.9, 0.1, 0.2, 0.9])
    ybry = np.array([0.9, 0.9, 0.1, 0.1])
    beta = np.array([1.0, 1.0, 1.0, 1.0])
    
    nx = 30
    ny = 30
    ul_idx = 0
    
    nnodes=14
    precision=1.0e-12
    nppe=3
    newton=True
    thin=True
    checksimplepoly=True
    verbose=True
    
    _libgridgen = np.ctypeslib.load_library('libgridgen.dll', '/home/Nikhil/python/octant/gridgen')
    
    print _libgridgen
    
    _libgridgen.gridgen_generategrid2.restype = ctypes.c_void_p
    _libgridgen.gridnodes_getx.restype = ctypes.POINTER(ctypes.POINTER(ctypes.c_double))
    _libgridgen.gridnodes_gety.restype = ctypes.POINTER(ctypes.POINTER(ctypes.c_double))
    _libgridgen.gridnodes_getnce1.restype = ctypes.c_int
    _libgridgen.gridnodes_getnce2.restype = ctypes.c_int
    
    _libgridgen.gridnodes_getnx.restype = ctypes.c_int
    _libgridgen.gridnodes_getny.restype = ctypes.c_int
    
    _libgridgen.gridmap_build.restype = ctypes.c_void_p
    
    
    nbry = len(xbry)
    
    nsigmas = ctypes.c_int(0)
    sigmas = ctypes.c_void_p(0)
    nrect = ctypes.c_int(0)
    xrect =  ctypes.c_void_p(0)
    yrect = ctypes.c_void_p(0)
    
    ngrid = ctypes.c_int(0)
    xgrid = ctypes.POINTER(ctypes.c_double)()
    ygrid = ctypes.POINTER(ctypes.c_double)()
    
    _gn = _libgridgen.gridgen_generategrid2(
     ctypes.c_int(nbry), 
     (ctypes.c_double * nbry)(*xbry), 
     (ctypes.c_double * nbry)(*ybry), 
     (ctypes.c_double * nbry)(*beta),
     ctypes.c_int(ul_idx), 
     ctypes.c_int(nx), 
     ctypes.c_int(ny), 
     ngrid, 
     xgrid, 
     ygrid,
     ctypes.c_int(nnodes), 
     ctypes.c_int(newton), 
     ctypes.c_double(precision),
     ctypes.c_int(checksimplepoly), 
     ctypes.c_int(thin), 
     ctypes.c_int(nppe),
     ctypes.c_int(verbose),
     ctypes.byref(nsigmas), 
     ctypes.byref(sigmas), 
     ctypes.byref(nrect),
     ctypes.byref(xrect), 
     ctypes.byref(yrect) )
    
    
     print 'run getx'
     x = _libgridgen.gridnodes_getx(_gn)
    
     print 'reshape result.'
     x = np.asarray([x[0][i] for i in range(ny*nx)])
     x.shape = (ny, nx)
    
    
     print 'run gety'
     y = _libgridgen.gridnodes_gety(_gn)
    
     print 'reshape result.'
     y = np.asarray([y[0][i] for i in range(ny*nx)])
     y.shape = (ny, nx)
    

# backtrace

    
    
    Program received signal SIGSEGV, Segmentation fault.
    0x0000000542596595 in gridnodes_getx (gn=0x45ab50) at gridnodes.c:789
    789         return gn->gx;
    (gdb) backtrace
    0  0x0000000542596595 in gridnodes_getx (gn=0x45ab50) at gridnodes.c:789
    

and this is the c code backtrace is referring to

    
    
    int gridnodes_getnx(gridnodes* gn)
    {
        return gn->nx;
    }
    
    int gridnodes_getny(gridnodes* gn)
    {
        return gn->ny;
    }
    
    double** gridnodes_getx(gridnodes* gn)
    {
        return gn->gx;
    }
    
    double** gridnodes_gety(gridnodes* gn)
    {
        return gn->gy;
    }
    

I would appreciate if some one can help me with this.


Answer: I managed to solve the issue by using a class

    
    
    class gridnodes (ctypes.Structure):
        _fields_ = [
        ('nx',ctypes.c_int), \
        ('ny',ctypes.c_int), \
        ('gx', ctypes.c_double), \
        ('gy', ctypes.c_double)]
    

and replacing

    
    
    _libgridgen.gridgen_generategrid2.restype = ctypes.c_void_p
    

by

    
    
    _libgridgen.gridgen_generategrid2.restype = ctypes.POINTER(gridnodes)
    

I also tried the suggestion by @eryksun and that works as well..

