I have a C++ header like this:
class A{
public:
A();
A(const double& x, const double& y, const double& z);
~A();
void initialize(const double& x, const double& y, const double& z);
double* get_vec(void); /* return a pointer to vec_ */
const double* get_vec(void) const; /* return a pointer to vec_ */
private:
double vec_[3];
};
I want to wrap it with Python so I can do:
a = demo.A(1.,2.,3)
coord = a.get_vec() # coord is a numpy array
I don't want to apply a typemap on all 'double*' returned value, because there
are of course not all 3-length vector.
A first solution would be to change the header file like this:
typedef double* SWIG_DOUBLE_VECTOR3;
typedef const double* SWIG_DOUBLE_VECTOR3_CONST;
class A{
...
SWIG_DOUBLE_VECTOR3 get_vec(void);
SWIG_DOUBLE_VECTOR3_CONST get_vec(void) const;
...
};
and then apply typemap on SWIG_DOUBLE_VECTOR3, SWIG_DOUBLE_VECTOR3_CONST, but it
would be better to not alter the header file.
Another solution is to %extend A with a get_vec_helper function, where the
returned value is now a argument, and apply a typemap on it. Then %ignore
get_vec, and %rename get_vec_helper to get_vec:
%module demo
%{
#define SWIG_FILE_WITH_INIT
#include "a.hpp"
%}
%include "numpy.i"
%init %{
import_array();
%}
%typemap(in,numinputs=0,fragment="NumPy_Fragments")
double *swig_argout_double_pointer_len3 (double* temp) {
temp = new double[3];
$1 = temp;
}
%typemap(argout) double* swig_argout_double_pointer_len3 {
int nd=1; /* a vector is 1 dimension */
npy_intp dims[nd];
dims[0] = 3; /* vector has 3 components */
$result = PyArray_SimpleNewFromData(nd,dims,NPY_DOUBLE,temp$argnum);
if (! $result) SWIG_fail;
}
%ignore A::get_vec;
%rename(get_vec) A::get_vec_helper;
%include "a.hpp"
%extend A {
void get_vec_helper(double *swig_argout_double_pointer_len3)
{
double *vec = $self->get_vec();
swig_argout_double_pointer_len3[0] = vec[0];
swig_argout_double_pointer_len3[1] = vec[1];
swig_argout_double_pointer_len3[2] = vec[2];
};
}
It's work. But it's quite complicated for apparently simple task...
Do you see anyway to make the process simpler?
Best,
David
------------------------------------------------------------------------------
This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here
http://p.sf.net/sfu/sfd2d-msazure
_______________________________________________
Swig-user mailing list
Swig...@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user
I just realized that typemaps defined in numpy.i can apply directly on get_vec_helper.
Here it is simpler (it works):
%module demo
%{
#define SWIG_FILE_WITH_INIT
#include "a.hpp"
%}
%include "numpy.i"
%init %{
import_array();
%}
%ignore A::get_vec;
%rename(get_vec) A::get_vec_helper;
%include "a.hpp"
%extend A {
void get_vec_helper(double ARGOUT_ARRAY1[3])
{
double *vec = $self->get_vec();
ARGOUT_ARRAY1[0] = vec[0];
ARGOUT_ARRAY1[1] = vec[1];
ARGOUT_ARRAY1[2] = vec[2];
};