用SWIG封装boost::ublas

1 投票
2 回答
1009 浏览
提问于 2025-04-15 22:16

我正在尝试在numpy和boost::ublas这两个层之间传递数据。因为swig无法正确解析ublas的头文件,所以我写了一个非常简单的包装器。下面是代码:

#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/lexical_cast.hpp>
#include <algorithm>
#include <sstream>
#include <string>

using std::copy;
using namespace boost;

typedef boost::numeric::ublas::matrix<double> dm;
typedef boost::numeric::ublas::vector<double> dv;

class dvector : public dv{
 public:
 dvector(const int rhs):dv(rhs){;};
 dvector();
 dvector(const int size, double* ptr):dv(size){
   copy(ptr, ptr+sizeof(double)*size, &(dv::data()[0]));
 }
 ~dvector(){}
};

还有一个看起来像这样的SWIG接口:

%apply(int DIM1, double* INPLACE_ARRAY1) {(const int size, double* ptr)}
class dvector{
 public:
 dvector(const int rhs);
 dvector();
 dvector(const int size, double* ptr);
       %newobject toString;
 char* toString();
       ~dvector();
};

我已经通过gcc 4.3和vc++9.0成功编译了它们。但是当我简单地运行:

a = dvector(array([1.,2.,3.]))

时,它出现了段错误(segfault)。这是我第一次在使用numpy时用swig,并且对数据转换和内存缓冲区传递的理解还不够全面。有没有人看到我明显遗漏了什么?我尝试用调试器跟踪,但它在python.exe的汇编部分崩溃了。我不知道这是swig的问题还是我这个简单包装器的问题。任何帮助都非常感谢。

2 个回答

3

你可能会对 pyublas 这个模块感兴趣。它可以在numpy数组和ublas数据类型之间进行转换,而且这个过程非常顺畅,不需要复制数据。

1

你可能想把

copy(ptr, ptr+sizeof(double)*size, &(dv::data()[0]));

替换成

copy(ptr, ptr+size, &(dv::data()[0]));

记住,在C/C++中,对指针进行加法或减法操作时,移动的距离是它所指向的数据类型大小的倍数。

祝好,

撰写回答