5

I need to add a new method to my swig template class, for example:

I am declaring a template class in myswig.i as follows:

%template(DoubleVector) vector<double>;

this will generate a class named "DoubleVector" in the generated .py file with some generated methods. lets suppose they are func1(), func2() and func3(). These are generated functions and i have no control over them. Now, if I want to add a new method called "func4()" to this class(DoubleVector), how may I do it? Is it possible?

I know of a identifier called %pythoncode but I could not use it to define a new function in this template class.

Flexo
  • 87,323
  • 22
  • 191
  • 272
Saurabh
  • 295
  • 3
  • 12

1 Answers1

10

Given an interface file like:

%module test

%{
#include <vector>
%}

%include "std_vector.i"
%template(DoubleVector) std::vector<double>;

The easiest way to add more functionality to DoubleVector is to write it in C++, in the SWIG interface file using %extend:

%extend std::vector<double> {
  void bar() {
    // don't for get to #include <iostream> where you include vector:
    std::cout << "Hello from bar" << std::endl;       
  }
}

this has the advantage that it would work for any language you target with SWIG, not just Python.

You can also do it using %pythoncode and an unbound function:

%pythoncode %{
def foo (self):
        print "Hello from foo"

DoubleVector.foo = foo
%}

Example running this:

Python 2.6.7 (r267:88850, Aug 11 2011, 12:16:10) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> d = test.DoubleVector()
>>> d.foo()
Hello from foo
>>> d.bar()
Hello from bar
>>> 
Community
  • 1
  • 1
Flexo
  • 87,323
  • 22
  • 191
  • 272
  • 1
    The trick is to `%extend` the full template name, not the abbreviated name. E.g., `%extend std::vector`, not `%extend DoubleVector`. – Paul Price Jul 22 '13 at 23:22
  • @Paul you can also use %extend within a class definition with no name and it applies to the current class. The swig library uses this quite a bit. – Flexo Jul 23 '13 at 06:55
  • 1
    In addition to the unbounded function, it seems to be possible as well to nest the `%pythoncode` into the `%extend` block: `%extend std::vector { %pythoncode %{ def foo(self): pass %} };` – user1556435 Jan 01 '18 at 12:56
  • That's true and something I only learned fairly recently myself – Flexo Jan 01 '18 at 13:07