0

我在 C++ 中有一个线性代数矩阵类,并希望使用 SWIG 为 Numpy 构建一个包装器。一切正常,但如果我想从 python 调用一个引用作为参数的函数,我会得到一个TypeError.

这是swig代码:

%{                                                                                                                                                                                                                                                                               
#define SWIG_FILE_WITH_INIT                                                                                                                                                                                                                                                      
%}                                                                                                                                                                                                                                                                               

%include "typemaps.i"                                                                                                                                                                                                                                                            
%include "numpy.i"                                                                                                                                                                                                                                                               
%module arraypy                                                                                                                                                                                                                                                                  
%{                                                                                                                                                                                                                                                                               
  #include "Core/array.h"                                                                                                                                                                                                                                                        
  #include "Core/array_t.h"                                                                                                                                                                                                                                                      
%}                                                                                                                                                                                                                                                                               

%fragment("NumPy_Fragments");                                                                                                                                                                                                                                                    

%init %{                                                                                                                                                                                                                                                                         
import_array();                                                                                                                                                                                                                                                                  
%}                                                                                                                                                                                                                                                                               


%typemap(in) Array<double> {                                                                                                                                                                                                                                                 
  if(is_array($input)) {                                                                                                                                                                                                                                                         
    uint size = 1;                                                                                                                                                                                                                                                               
    for(uint i=0; i<array_numdims($input); ++i)                                                                                                                                                                                                                                  
      size *= array_size($input, i);                                                                                                                                                                                                                                             
    $1.resize(size);                                                                                                                                                                                                                                                             

    memcpy($1.p, array_data($input), size*sizeof(double));                                                                                                                                                                                                                       
    $1.nd = array_numdims($input);                                                                                                                                                                                                                                               
    $1.N = size;                                                                                                                                                                                                                                                                 
    $1.d0 = array_size($input, 0);                                                                                                                                                                                                                                               
    $1.d1 = array_size($input, 1);                                                                                                                                                                                                                                               
    $1.d2 = array_size($input, 2);                                                                                                                                                                                                                                               
  }                                                                                                                                                                                                                                                                              
}                                                                                                                                                                                                                                                                                

%typemap(out) Array<double> {                                                                                                                                                                                                                                                
  long dims[3] = { $1.d0, $1.d1, $1.d2 };                                                                                                                                                                                                                                        
  PyArrayObject *a = (PyArrayObject*) PyArray_SimpleNew($1.nd, dims, NPY_DOUBLE);                                                                                                                                                                                                
  memcpy(PyArray_DATA(a), $1.p, $1.N*sizeof(double));                                                                                                                                                                                                                            
  $result = PyArray_Return(a);                                                                                                                                                                                                                                                   
}                                                                                                                                                                                                                                                                                

%inline %{                                                                                                                                                                                                                                                                       
void testing(Array<double>& a) {                                                                                                                                                                                                                                          
  std::cout << a << endl;                                                                                                                                                                                                                                                        
}                                                                                                                                                                                                                                                                                
%}

如果我现在运行例如 ipython:

$ import arraypy
$ import numpy
$ arraypy.testing(numpy.array([1, 2, 3]))

我得到TypeError: in method testing, argument 1 of type ¨Array< double > &¨ 如果我添加一个特定的类型映射来Array<double> &复制工作的类型,它不会编译,因为$1不知何故得到了一个指针。如果我考虑到这一点,我会得到一个段错误。

如何使包装器也与引用一起使用?(当然对于指针而不是引用也是如此)

4

1 回答 1

0

http://www.swig.org/Doc2.0/SWIGPlus.html#SWIGPlus_nn18中所述,SWIG 将引用转换回指针。

所以我的第一次尝试是正确的:只需复制类型映射以获取引用和指针。段错误是由不同的东西引起的。为了使一切都变得更好,可以使用片段。

于 2013-10-23T13:15:46.213 回答