I have a C++ API I'm trying to wrap in Python. I want to call a wrapped C++ function myfunc taking as an argument the following C++ typedef
/* my_header.h */
namespace my_namespace {
typedef std::vector<Foo> Bar
}
where Foo is a C++ class. I managed to wrap the function and the underlying class Foo, but I don't know how to create the vector of Foo. I included the .h file in my SWIG .i file as follows
/* my_interface.i */
%{
#include "my_header.h"
typedef my_namespace::Bar Bar;
%}
%include "my_header.h"
I also tried wrapping the std::vector template in SWIG, as follows
%include std_vector.i
namespace std {
%template(vector_foo) vector<Foo>;
}
This works, and I can import vector_foo in Python. However, when I send a vector_foo as an argument to the function mentioned above, I get a TypeError. Neither am I able to populate vector_foo with Foo.
In Python I do the following
>>> a = mymodule.vector_foo()
>>> a
<Swig Object of type 'std::vector <Foo, std::allocator< Foo > > *'
>>> mymodule.myfunc(a, 'string')
TypeError: in method 'myfunc', argument 1 of type 'my_namespace::Bar &'
Either if I can make my own implementation of vector of Foo work, or somehow access the C++ typedef directly. I'm calling SWIG and compiling using Python Distutils.
Thanks for any help!
To build Python extension modules, SWIG uses a layered approach in which parts of the extension module are defined in C and other parts are defined in Python. The C layer contains low-level wrappers whereas Python code is used to define high-level features.
We use the SWIG %apply directive to apply the typemap for one-dimensional input arrays of type double to the actual prototype used by rms . Using numpy. i effectively, therefore, requires knowing what typemaps are available and what they do.
The Simplified Wrapper and Interface Generator (SWIG) is an open-source software tool used to connect computer programs or libraries written in C or C++ with scripting languages such as Lua, Perl, PHP, Python, R, Ruby, Tcl, and other languages like C#, Java, JavaScript, Go, D, OCaml, Octave, Scilab and Scheme.
The most common format of a SWIG interface is as follows: %module mymodule %{ #include "myheader. h" %} // Now list ANSI C/C++ declarations int foo; int bar(int x); ... The module name is supplied using the special %module directive.
I solved it.
Seems like the problem was I had to tell SWIG about the typedef already present in the %{ %} braces in the interface file, i.e.
/* my_interface.i */
%{
#include "my_header.h"
typedef my_namespace::Bar Bar;
%}
typedef my_namespace::Bar Bar;
%include "my_header.h"
Although I'm not 100% that this was the mistake. In any case, I now have an interface file like the above one and wrapping works.
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