SWIG将C++转换为Python:向量问题

3

我正在遵循这里的文档:http://www.swig.org/Doc3.0/Library.html#Library_stl_cpp_library编写一个包装器,用于涉及矢量的简单示例代码。

以下是头文件:

### 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;
};

源文件如下:

### 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
*/

以下是接口文件:

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

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

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

%include "word.h"

我的编译步骤如下:

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中创建对象时,我得到了以下错误:
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 > > &'

一番在线搜索后,我认为在SWIG定义中使用模板可以解决这个问题。
然而,在我的情况下并没有。您能指点一下我该如何做吗?
1个回答

2

它不起作用,因为你通过引用传递了向量。如果你改为按值或按const引用传递,SWIG就知道该怎么做并生成正确的代码。只需在声明和定义中更改类型即可。

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

足够了。
$ 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])

在这种情况下,您可以应用上述调整,因为您不需要values成为裸引用。如果需要引用,则需要更多的工作,并且您必须编写自己的类型映射(以及可能是自己的容器)。

如果我真的想在我的C++函数中使用(并修改)std::vector而不进行复制,我可以有哪些替代方案?std::vector的原始指针?std::vector的shared_ptr?(我也在这里提问了)。 - Gabriel Devillers
1
@GabrielDevillers 你不能通过 C++ 向量查看 Python 列表,因为按定义,向量拥有其内存。如果你使用的是 NumPy 数组而不是列表,则可以使用 numpy.i SWIG 绑定获取指向底层数组的指针,并直接在原地修改它:https://numpy.org/doc/stable/reference/swig.interface-file.html#in-place-arrays - Henri Menke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接