Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing C++ typedef in Python using SWIG

Tags:

c++

python

swig

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!

like image 704
fhal Avatar asked Nov 16 '11 16:11

fhal


People also ask

How does SWIG work Python?

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.

Does Numpy use SWIG?

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.

What is SWIG object Python?

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.

How do I create a swig interface?

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.


1 Answers

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.

like image 161
fhal Avatar answered Oct 20 '22 01:10

fhal