I created a sample SWIG wrapper to test this:
%module test
%{
#include <stdlib.h>
#include <stdio.h>
double* get(void)
{
double* p = malloc(sizeof(double) * 10);
for(int i = 0; i < 10; ++i)
p[i] = 1.1 * i;
printf("%p\n",p);
return p;
}
%}
double* get(void);
The following retrieves the data via ctypes:
>>> import test
>>> a = test.get()
000001A3D05ED890 # From the printf...
>>> a
<Swig Object of type 'double *' at 0x000001A3D27D6030>
>>> hex(int(a))
'0x1a3d05ed890' # int() of the object is the same address
>>> from ctypes import *
>>> p = (c_double * 10).from_address(int(a))
>>> list(p)
[0.0, 1.1, 2.2, 3.3000000000000003, 4.4, 5.5, 6.6000000000000005, 7.700000000000001, 8.8, 9.9]
Now for numpy. There may be a better way, but I found __array_interface__
(link). An "array-like" object has this interface and another array can be created from it:
>>> class Tmp: pass
...
>>> Tmp.__array_interface__ = {'shape':(10,),'typestr':'<f8','data':(int(a),False),'version':3}
>>> import numpy as np
>>> np.array(Tmp,copy=False) # Create array that shares the same interface
array([0. , 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9])
Maybe not the best way, but I'm not a heavy user of numpy.