2012/7/29 David Froger <david.froger@gmail.com>
Hi Oliver,

> the numpy.i interface provides us with most of the items I need for a
> project, however, I have a case whereby I build an array in C++ and need to
> pass it to numpy. The size of the array is unknown at the beginning, so I
> cannot use the numpy.i typedefs for ARGOUT_ARRAY1 (as these require you to
> supply the dimension of the array to be returned).

Could argoutview arrays be what you need?
http://docs.scipy.org/doc/numpy/reference/swig.interface-file.html#argoutview-arrays

I don't think so, unless I'm missing the point of argoutview. From the example at http://www.scipy.org/Cookbook/SWIG_NumPy_examples , it looks like here too the size of the array to be returned is known at compile time, which is not the case.


> ======= test.cxx =========
> #include "test.h"
> #include <iostream>
> #include <Python.h>
> #include <numpy/npy_common.h>
> #include <numpy/arrayobject.h>
>
> using namespace std;
> void func(double * points, int nbr_points, PyObject **py_A)

I'm not sure what 'func' do. Why is there a PyObject **py_A argument?

That's actually the name of the array to be returned, the points and nbr_points data is merely used to pass 1 array (points) in, together with its dimensions (nbr_points). But inside func, a new array gets created (py_A) which should be returned to numpy (probably together with its dimensions, which are known only at runtime). In your comment below, you continue with points as the output array, which is just as good, my example wasn't clear).


Could it be re-written like this? :

    void func(double ** points, int * nbr_points) {
      C++ allocate and give values to points and nbr_points
    }

    When this function is called from Python, a typemap convert
    (double **npoints, int *nbr_points) to a numpy array.

Regards,
David


Yes, I believe you understand the required functionality. Just to confirm, the function could be called without any arguments from Python, it just needs to return a numpy array (or 2, so the C++ code cannot simply return a pointer). Another example of the required function would be (with some pseudo code):

=== Python call ===
(a,b) = test.return_2_random_arrays()

=== C++ ===
void return_2_random_arrays(double * points, int * points_dimensions, double * serial_numbers, int * serial_numbers_dim)
{
// points is an nx2 array
int rows = rand();
points_dimensions = {rows, 2};
points = new double[rows * 2];
// some functionality here to fill this contiguous array with random data

// serial_numbers is an mx1 array
rows = rand(); // take another number for m
serial_numbers_dim = {rows, 1};
serial_numbers = new double[ rows ];
// some functionality here to fill this array
}

Thanks in advance,

Oliver