如何使用Python列表将std::vector赋值给C++中的SWIG?

10 投票
2 回答
8502 浏览
提问于 2025-04-17 22:53

我有一个简单的C++类,这个类里面有一个std::vector成员,还有一个接收std::vector作为参数的成员函数。我正在用SWIG把它包装起来,以便在Python中调用。下面是示例代码。

编译完成后,我进入Python并执行:

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

我收到的错误信息是:

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

我知道我可以这样做:

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

但我想知道如何直接在赋值中使用Python列表,或者至少理解为什么这样不行。


以下是示例代码。

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 个回答

0

你可以看看SWIG文档中的typemaps示例章节:http://www.swig.org/Doc2.0/SWIGDocumentation.html#Typemaps_nn40(在示例的最后部分,讨论了如何访问结构体)。

你可能需要为你的数据成员添加一个memberin的typemap,如果SWIG的std_vector.i没有提供的话,可能还需要添加outin

5

试着在 Test::data 这个成员上使用 %naturalvar 指令。在你的 test.i 文件中:

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

根据SWIG的文档,关于 CC++ 的成员,SWIG 默认是通过指针来访问嵌套的结构体和类。使用 %naturalvar 指令可以让接口通过值来访问,而不是通过引用。

撰写回答