python - 使用 Swig 通过 Python 包装 Eigen/C++ 时出错

标签 python c++ swig

我在使用 SWIG 封装一个使用 Eigen(线性代数包)的小项目时遇到问题。我收到一个 python 错误,我不明白并且在网上找不到太多相关信息 - 但我怀疑某处存在一些 C++ 内存损坏。我将其归结为一个玩具示例..但不幸的是它仍然很长:

--- testfunc.cxx ----

#include "Eigen/Dense" 

Eigen::VectorXd test(Eigen::MatrixXd data){ 
        Eigen::VectorXd temp; 
        return temp; 
} 

--- testwig.i -----

%module testswig 

%{ 
#define SWIG_FILE_WITH_INIT 
#include "Eigen/Core" 
#include <Python.h>
#include <numpy/arrayobject.h>
#include "testfunc.cxx" 

%} 

%init 
%{ 
  import_array(); 
%} 

%include "numpy.i" 

%typemap(out) Eigen::VectorXd 
{ 
    npy_intp dims[1] = {$1.size()}; 
    PyObject* array = PyArray_SimpleNew(1, dims, NPY_DOUBLE); 
    double* data = ((double *)PyArray_DATA( array )); 
    for (int i = 0; i != dims[0]; ++i){ 
        *data++ = $1.data()[i]; 
    } 
    $result = array; 
} 

%typemap(in) Eigen::MatrixXd (Eigen::MatrixXd TEMP) 
{ 

  int rows = 0; 
  int cols = 0; 

  rows = PyArray_DIM($input,0); 
  cols = PyArray_DIM($input,1); 

  PyArrayObject* temp; 
  PyArg_ParseTuple($input, "O", &temp);   

  TEMP.resize(rows,cols); 
  TEMP.fill(0); 

  double *  values = ((double *) PyArray_DATA($input)); 
  for (long int i = 0; i != rows; ++i){ 
      for(long int j = 0; j != cols; ++j){ 
          // std::cout << "data " << data[i] << std::endl; 
          TEMP(i,j) = values[i*rows+j]; 
      } 
  }   

} 

%include "testfunc.cxx" 

--- setup.py ----

from distutils.core import setup, Extension 
import numpy 
numpyinclude = numpy.__file__[:-12] + 'core/include/' 
testswig = Extension('_testswig', 
                     sources=['testswig_wrap.cxx'], 
                     include_dirs=['../', numpyinclude]) 

setup (name = 'testswig', 
       version = '0.1', 
       author      = "NoName", 
       description = """ """, 
       ext_modules = [testswig], 
       py_modules = ["testswig"]) 

-----建筑------

我正在一个包含所有 3 个文件的文件夹和一个包含 Eigen header 的文件夹“Eigen”中构建它。命令是:

swig -c++ -python -I./ testswig.i 
python setup.py install 

-----错误----------

然后我运行一个包含

的 python 文件
import testswig 
import numpy as np 
print testswig.test(np.array([[2,3],[4,5]])) 

这给出了错误“SystemError: new style getargs format but argument is not a tuple”。

注意几点: 1) 相同的命令直接从 python 解释器运行良好。 2) 如果函数不返回 Eigen::VectorXd,或者不采用 Eigen:MatrixXd,则它可以正常工作。

感谢您的宝贵时间。

最佳答案

在您的类型映射中,您有:

PyArrayObject *temp;
PyArg_ParseTuple($input, "O", &temp);

这是不正确的 - $input 是一个 PyObject,已在此阶段从参数中提取,但不是元组,因此您需要:

PyArrayObject *temp=NULL;
if (PyArray_Check($input))
    temp = (PyArrayObject*)$input;

验证它的类型是否正确,如果是,则进行强制转换。

关于python - 使用 Swig 通过 Python 包装 Eigen/C++ 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24375198/

相关文章:

python - 如何将常规 numpy 数组转换为记录数组?

c++ - 我相信这是 clang 中的一个错误,与构造函数抛出的放置新表达式有关

c++ - SWIG:std/multimap.i 似乎因 Tcl 包装而损坏

c++ - 如何在 SDL 2.0 中实时获取所有事件的 "list"?

c# - 为 C++ 模板扩展 C# 代理类

python - 用 python 反汇编 - 没有简单的解决方案?

python - 如何从 sqlalchemy 映射创建表

python - 在django中扩展用户模型后,我无法登录

python - 错误: Could not find a version that satisfies the requirement azure-functions

c++ - MPI如何从从节点接收动态数组?