本文介绍了SWIG c++ to python:向量问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在关注此处的文档:http://www.swig.org/Doc3.0/Library.html#Library_stl_cpp_library 为涉及向量的简单示例代码编写包装器.

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.

这里是头文件:

### 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 中创建对象时,出现以下错误:

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 > > &'

网上的一些搜索让我相信在 SWIG 定义中使用模板可以解决这个问题.

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?

推荐答案

它不起作用,因为您通过引用传递了向量.如果您改为按值或按常量引用传递,则 SWIG 知道该怎么做并生成正确的代码.只需更改

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);

足够了.

$ 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 作为裸参考.如果需要引用,则需要做更多工作,并且您必须编写自己的类型映射(也可能是您自己的容器).

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).

这篇关于SWIG c++ to python:向量问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 05:52