SWIG c++ to python : vector problems

跟風遠走 提交于 2021-02-08 01:49:10

问题


I am following the documentation here: http://www.swig.org/Doc3.0/Library.html#Library_stl_cpp_library to write a wrapper to a simple example code involving vectors.

Here is the header file:

### word.h ###
#include<string>
#include<vector>

class Word{
public:
    Word(std::string word, int numWords, std::vector<double> &values);
    ~Word();

    void updateWord(std::string newWord);
    std::string getWord();
    void processValues();

private:
    std::string theWord;
    int totalWords;
    std::vector<double> values;
};

And the source file:

### word.cpp ###
#include "word.h"
#include <cfloat>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <time.h>

Word::Word(std::string word, int numWords, std::vector<double> &values) :
    theWord(word), totalWords(numWords), values(values){
    // TODO: constructor
}

Word::~Word() {
    // TODO: destructor
}

void Word::updateWord(std::string newWord) {
    this->theWord = newWord;
}

std::string Word::getWord() {
    return this->theWord;
}

void Word::processValues() {
    values.resize(totalWords);
    // do something with values here
}

/*  
    rest of the code that uses the other imports
*/

Here is the interface file:

### word.i ###
%module word
%{
#include "word.h"
%}

%include "std_string.i"
%include "std_vector.i"

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

%include "word.h"

My compilation steps are as follows:

swig -c++ -python word.i
g++ -c -fpic word.cpp word_wrap.cxx -I/usr/include/python2.7
g++ -shared word.o word_wrap.o -o _word.so -lstdc++

The compilation goes through without any errors. However, on trying to create the object in Python I get the following error:

In [1]: import word

In [2]: w = word.Word('test', 10, [10.2])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-ee2e5c406fd9> in <module>()
----> 1 w = word.Word('test', 10, [10.2])

/home/anarayan/workspace/swig-learn/word.pyc in __init__(self, word, numWords, values)
    276 
    277     def __init__(self, word, numWords, values):
--> 278         this = _word.new_Word(word, numWords, values)
    279         try:
    280             self.this.append(this)

TypeError: in method 'new_Word', argument 3 of type 'std::vector< double,std::allocator< double > > &'

A bit of searching online leads me to believe that using the template in the SWIG definition solves this problem.

However, in my case it hasn't. Could you please point me in the right direction?


回答1:


It doesn't work because you passing the vector by reference. If you instead pass by value or by const reference SWIG knows what to do and generates the correct code. Simply changing the type in the declaration and defintion of

Word(std::string word, int numWords, std::vector<double> const &values);

is sufficient.

$ swig -c++ -python word.i
$ g++ -c -fpic word.cpp word_wrap.cxx -I/usr/include/python2.7
$ g++ -shared word.o word_wrap.o -o _word.so -lstdc++
$ python
Python 2.7.13 (default, Nov 24 2017, 17:33:09) 
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import word
>>> w = word.Word('test', 10, [10.2])

In this case you can apply the above adjustments because you don't need values to be a bare reference. If a reference is needed more work is required and you have to write your own typemap (and probably your own container).



来源:https://stackoverflow.com/questions/51466189/swig-c-to-python-vector-problems

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!