如何在swig中引用类型化的类?

时间:2013-10-22 14:13:08

标签: c++ python swig

我在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以某种方式获得了一个指针。如果我考虑到这一点,我会得到一个段错误。

如何使包装器也可以使用引用? (对于指针而不是引用,当然也是如此)

1 个答案:

答案 0 :(得分:0)

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

所以我的第一个尝试是正确的:只需复制引用和指针的类型图。段错误源于不同的东西。为了使一切都好一点,可以使用fragmet。