I have a C++ library that defines the following (and more like them) types:
typedef std::vector< double > DoubleVec;
typedef std::vector< DoubleVec > DoubleVecVec;
typedef std::vector< int > IntVec;
typedef std::vector< IntVec > IntVecVec;
I am trying to create a python interface to a library that handles objects like that. As the title states, I would like my interface to convert to/from C++ std::vector
and numpy ndarray
.
I have seen both numpy.i
provided by the numpy people and std_vector.i
from the SWIG people. The problems are that numpy.i
was created to handle C/C++ arrays (not C++ vectors) and std_vector.i
doesn't do conversion directly to/from numpy arrays.
Any ideas?
I have seen that the FEniCS project has done something like this, but their project is so large that I am having a hard time finding out just how they do this specific task.
Wrapping C/C++ for Python using SWIG 1 Installation. ... 2 My c file is example.c 3 Interface file: Now, if you want to add you c file to your preferred language, you need to write an “interface file” which is the input to SWIG. 4 example.i. ... 5 Header file. ... 6 example.h 7 Setup file: 8 Creating the wrapper. ... 9 Built the extension. ...
So, for the given task – Swig Wrapper Generator is used. Swig operates by parsing C header files and automatically creating extension code. C-header file is needed first, to use Swig. Give an example of C-header file in the code below. After having the header file, the next step is to write a Swig “interface” file.
In Python, there is no detailed distinction like this--specifically, there are only "objects". There are no pointers, references, arrays, and so forth. Because of this, SWIG unifies all of these types together in the wrapper code. For instance, if you actually had the above functions, it is perfectly legal to do this:
When SWIG does not convert them, it will generate code to obtain them from the C++ layer as if python:cdefaultargs was specified. This will happen if just one argument cannot be converted into a Python equivalent. This occurs typically when the argument is not fully numeric, such as int (1) :
Try this as a starting point.
%include "numpy.i"
%apply (size_t DIM1, double* IN_ARRAY1) {(size_t len_, double* vec_)}
%rename (foo) my_foo;
%inline %{
int my_foo(size_t len_, double* vec_) {
std::vector<double> v;
v.insert(v.end(), vec_, vec_ + len_);
return foo(v);
}
%}
%apply (size_t DIM1, size_t DIM2, double* IN_ARRAY2) {(size_t len1_, size_t len2_, double* vec_)}
%rename (bar) my_bar;
%inline %{
int my_bar(size_t len1_, size_t len2_, double* vec_) {
std::vector< std::vector<double> > v (len1_);
for (size_t i = 0; i < len1_; ++i) {
v[i].insert(v[i].end(), vec_ + i*len2_, vec_ + (i+1)*len2_);
}
return bar(v);
}
%}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With