C++ & SWIG: using data pointed to by a pointer
SWIG is an excellent, widely used, tool for wrapping C and C++ libraries for use in higher level languages. Learning how to best use SWIG is, as is true with all programming languages, not trivial.
Consider wrapping a C++ class like this:
class MyData {
std::vector<double> d;
public:
MyData(size_t n);
double& operator()(size_t i);
};
We wish to use function operator() to access the value at the i-th element within our data structure (which in fact is itself a trivial wrapper for std::vector but that is unimportant for this example).
If this class declaration is included into the SWIG interface file simply by say:
%include "mydata.h"
the operator() function will get wrapped, and it will return a pointer to a double. For example, in Python, one gets something like:
>>> import mydata
>>> x=mydata.MyData(3)
>>> x(1)
<Swig Object of type 'double *' at 0x1b601c8>
This of course is very much the essence of what the class declaration specifies, but how do we use this pointer in the target language to access the data that it points to?
The answer is by using the cpointer.i SWIG library and the %pointer_functions function which provide facilities for accessing data pointed to by pointers (documentation). In the present case we would add something like:
%include "cpointer.i"
%pointer_functions(double ,doubleP)
in the interface file which will then define functions like doubleP_assign and doubleP_value in the generated module. These can then be used to access the data that the pointer points to:
>>> # Create a MyData object with 3 elements
>>> x=mydata.MyData(3)
>>> # Check what the value of second element is
>>> mydata.doubleP_value(x(1))
0.0
>>> # Assign value 3 to second element
>>> mydata.doubleP_assign(x(1), 3)
>>> # Check what the value of second element is
>>> mydata.doubleP_value(x(1))
3.0