11

I have a simple C++ class that contains a std::vector member and a member function that takes a std::vector as an argument that I am wrapping with SWIG and calling from Python. The example code is below.

After compiling it, I go into Python and do:

import test
t = test.Test()
a = [1, 2, 3]
b = t.times2(a) # works fine
t.data = a # fails!

The error message I get is:

TypeError: in method 'Test_data_set', argument 2 of type 'std::vector< double,std::allocator< double > > *'

I know that I can just do:

t.data = test.VectorDouble([1,2,3])

But I would like to know how to just use a Python list directly in the assignment, or at least understand why it doesn't work.


Here's the example code.

test.i:

%module test

%include "std_vector.i"

namespace std {
    %template(VectorDouble) vector<double>;
};

%{
#include "test.hh"
%}

%include "test.hh"

test.hh:

#include <vector>

class Test {
    public:
        std::vector<double> data;
        std::vector<double> times2(std::vector<double>);
};

test.cc:

#include "test.hh"

std::vector<double>
Test::times2(
    std::vector<double> a)
{
    for(int i = 0; i < a.size(); ++i) {
        a[i] *= 2.0;
    }
    return a;
}

makefile:

_test.so: test.cc test.hh test.i
    swig -python -c++ test.i
    g++ -fpic -shared -o _test.so test.cc test_wrap.cxx -I/opt/local/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -L/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config/ -lpython2.7

2 Answers 2

5

Try using the %naturalvar directive on the Test::data member. In your test.i file:

%naturalvar Test::data;
%include "test.hh"

As described in the SWIG documentation on C and C++ members, SWIG will default to accessing nested structs and classes via pointers. The %naturalvar directs the interface to be accessed by value rather than by reference.

Sign up to request clarification or add additional context in comments.

1 Comment

However, now I can't change the elements of data. If I do t = test.Test(); t.data = [1, 2, 3]; t.data[0] = 4, it fails on the last line and says "'tuple' object does not support item assignment".
0

Have a look at the typemaps example chapter from the SWIG documentation: http://www.swig.org/Doc2.0/SWIGDocumentation.html#Typemaps_nn40 (at the end of the example where it discusses struct access).

You probably need to add a memberin typemap for your data member, and maybe out and in as well, if those are not already provided by SWIGs std_vector.i.

1 Comment

The memberin typemap applies to an already converted input. The error seems to be occurring before that. The wrapper for times2 calls swig::asptr, which works, while the wrapper for setting the data variable calls SWIG_ConvertPtr, which fails. So maybe you are on the right track, but I need to find the proper typemap to fix...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.