within a framework of a simulation of some biophysical model I have a C++ class that implements my model with a member function that needs return a PyArrayObject*. The class is defined in the header file ng_networks.h which reads something like:
#include <stdio.h>
#include <math.h>
#include <Python.h>
#include <numpy/arrayobject.h> /* Numpy as seen from C */
struct ngn{...};  /* Structure of model parameter */  
class ngn_rate{   /* Model Class */
    int NEQ;
    ngn pars;
    double *y,*dy;
    public:
        ngn_rate();   // Constructor
        ~ngn_rate();  // Destructor
        PyObject* bifsystem();
}
ngn_rate::ngn_rate(){
    // Set ngn pars default values 
    ...
    // Allocate memory for model variables and RHS of equations
    y = (double*)calloc(NEQ,sizeof(double));
    dy = (double*)calloc(NEQ,sizeof(double));
}
ngn_rate::~ngn_rate{
    free(y);
    free(dy);
}
PyObject* ngn_rate::bifsystem(){
    long int NUMEL = NEQ; // PyArray creation function requires (long int*)
    // Does some operations on y,dy
    ...
    // Build PyObject* from dy
    // Create Python Array Object...
    PyObject* out_array = PyArray_SimpleNew(1,&NUMEL,NPY_DOUBLE);
    // ... and make C pointer to point to it
    double* dy_aux = (double*)((PyArrayObject*)out_array)->data;
    // Copy dy into PyObject out_array
    for(int i=0;i<NUMEL;i++) dy_aux[i] = dy[i];
    return out_array; 
}
As you may guess this class is eventually called from a Python module. With this regard I am using scipy.weave to interface my C code with Python. So the calling Python module looks something like:
def ngn_rate_py():
    support_code = """
                   #include <Python.h>
                   #include "ng_networks.h" 
                   """
    source_files = [...] # A list of C/CPP source file names
    libs = ['m']
    dirs = [...]         # A list of #include dirs
    # My C code to interface with Python
    code = """
       //Initialize Model 
       ngn_rate network();
       //Return dy_dt
       return_val = network.bifsystem();
       """
    vars = []
    dy   = weave.inline(code,
                        vars,
                        support_code = support_code,
                        sources = source_files,
                        libraries = libs,
                        library_dirs = dirs,
                        include_dirs = dirs,
                        runtime_library_dirs = dirs,
                        type_converters = converters.blitz,
                        compiler = 'gcc',
                        extra_compile_args = ['-std=c++11'],
                        force = 1)
    return dy
When I run the above module unfortunately it produces a segmentation fault. After some debugging and trial-and-error I figured out that the problem is caused for some reason by the initialization of PyObject* out_array in ng_networks.h. Indeed when I create the PyObject* in C code in weave it works perfectly: that is I modify the ngn_rate::bifsystem() class member function so that it returns a double* and then I build the PyObject* from the latter within the weave interface:
class ngn_rate{   /* Model Class */
    ...
    public:
        ...
        double* bifsystem();
}
double* ngn_rate::bifsystem(){
    long int NUMEL = NEQ; // PyArray creation function requires (long int*)
    // Does some operations on y,dy
    ...
    return dy;
}
And then in the weave interface:
def ngn_rate_py():
    support_code = """
                   #include <Python.h>
                   #include "ng_networks.h" 
                   """
    code = """
           //Initialize Model 
           ngn_rate network();
           //Create temporary dy  
           double *dy = network.bifsystem();
           //Create PyObject*
           PyObject* out_array = PyArray_SimpleNew(1, &NUMEL, NPY_DOUBLE);
           double* dy_aux = (double*) ((PyArrayObject*) out_array)->data;
           //Assign dy to PyObject            
           for(int i=0;i<NUMEL;i++) dy_aux[i]=dy[i];
           return_val = out_array;
I cannot figure out why the above works whereas I get a segmentation fault if I make PyObject* be returned by my class. Noteworthy is that in some other code I had just a static/non-member C-function that returned a PyObject* that when called from weave worked just fine. So my guess is that there are some issues with PyObject* used within C class object. But I cannot figure out what. And although I can work with the above code creating the PyObject* within the weave interface, for portability I'd rather have it directly provided by my class ngn_rate.
Thanks in advance for your feedback.
M
