使用 SWIG 将 C++ <vector> 包装为 python NumPy 数组

Posted

技术标签:

【中文标题】使用 SWIG 将 C++ <vector> 包装为 python NumPy 数组【英文标题】:Use SWIG to wrap C++ <vector> as python NumPy array 【发布时间】:2013-05-04 18:20:46 【问题描述】:

我有一个 C++ 库,它定义了以下(以及更多类似的)类型:

typedef std::vector< double > DoubleVec;

typedef std::vector< DoubleVec > DoubleVecVec;

typedef std::vector< int > IntVec;

typedef std::vector< IntVec > IntVecVec;

我正在尝试为处理此类对象的库创建一个 python 接口。正如标题所述,我希望我的界面能够与 C++ std::vector 和 numpy ndarray 相互转换。

我看到了 numpy 人提供的 numpy.i 和 SWIG 人提供的 std_vector.i。问题是 numpy.i 是为处理 C/C++ 数组(不是 C++ 向量)而创建的,而 std_vector.i 不直接与 numpy 数组进行转换。

有什么想法吗?

我看到FEniCS 项目做过类似的事情,但他们的项目太大了,我很难弄清楚他们是如何完成这项特定任务的。

【问题讨论】:

【参考方案1】:

尝试以此为起点。

%include "numpy.i"

%apply (size_t DIM1, double* IN_ARRAY1) (size_t len_, double* vec_)

%rename (foo) my_foo;
%inline %
int my_foo(size_t len_, double* vec_) 
    std::vector<double> v;
    v.insert(v.end(), vec_, vec_ + len_);
    return foo(v);

%

%apply (size_t DIM1, size_t DIM2, double* IN_ARRAY2) (size_t len1_, size_t len2_, double* vec_)

%rename (bar) my_bar;
%inline %
int my_bar(size_t len1_, size_t len2_, double* vec_) 
    std::vector< std::vector<double> > v (len1_);
    for (size_t i = 0; i < len1_; ++i) 
        v[i].insert(v[i].end(), vec_ + i*len2_, vec_ + (i+1)*len2_);
    
    return bar(v);

%

【讨论】:

以上是关于使用 SWIG 将 C++ <vector> 包装为 python NumPy 数组的主要内容,如果未能解决你的问题,请参考以下文章

包装 std::vector 的 std::vectors,C++ SWIG Python

如何使用 SWIG 将 numpy 数组转换为 vector<int>&(参考)

如何使用 Python 列表在 C++ 中使用 SWIG 分配 std::vector?

使用 SWIG 将 numpy 数组元素(int)传递给 c++ int

如何在 SWIG 中将向量的锯齿状 C++ 向量转换(类型映射)为 Python

SWIG 如何正确包装 std::vector<double *>