ctypes:初始化数组数组并传递给C函数

时间:2013-12-23 23:37:38

标签: c++ python ctypes

我一直在欺骗ctypes并遇到两个问题:

问题1。我想使用cellComplex数组构建double*,但我希望new_cellComplex接受double*数组'(以及size_t参数)而不是固定数量的double*。使用固定数字,代码看起来像(运行正常)

extern "C" {
  void * new_cellComplex(double* p_x, double* p_y, double* p_z) {

    std::vector< std::pair<double,double> > point;
    point.push_back( std::make_pair(p_x[0],p_x[1])); 
    point.push_back( std::make_pair(p_x[0],p_x[1])); 
    point.push_back( std::make_pair(p_x[0],p_x[1])); 

    cellComplex<double>* cmplx = new cellComplex<double>(point);
    return cmplx;
  }

使用Python代码:

import ctypes

cellComplex_lib = ctypes.cdll.LoadLibrary('./cellComplex_lib.so')
cellComplex_lib.new_cellComplex.restype  = ctypes.c_void_p
cellComplex_lib.new_cellComplex.argtypes = [ctypes.c_double*2,
                                            ctypes.c_double*2,
                                            ctypes.c_double*2]

p_x = (ctypes.c_double*2)(0.0,1.0)
p_y = (ctypes.c_double*2)(0.0,1.0)
p_z = (ctypes.c_double*2)(0.0,1.0)

cmplx = cellComplex_lib.new_cellComplex(p_x,p_y,p_z)

我宁愿拥有以下(哪些段错误)

extern "C" {
  void * new_cellComplex(double** p, size_t dim) {

    std::vector< std::pair<double,double> > point;
    for (size_t i=0; i<dim; ++i) {
      point.push_back( std::make_pair(p[i][0],p[i][1])); 
    } 
    cellComplex<double>* cmplx = new cellComplex<double>(point);
    return cmplx;
  }
}

使用Python代码:

import ctypes

dim = 3
cellComplex_lib = ctypes.cdll.LoadLibrary('./cellComplex_lib.so')
cellComplex_lib.new_cellComplex.restype  = ctypes.c_void_p
cellComplex_lib.new_cellComplex.argtypes = [(ctypes.c_double*2)*dim,
                                            ctypes.c_size_t]

p_x = (ctypes.c_double*2)(0.0,1.0)
p_y = (ctypes.c_double*2)(0.0,1.0)
p_z = (ctypes.c_double*2)(0.0,1.0)

p = ((ctypes.c_double*2)*dim)(p_x,p_y,p_z)

cmplx = cellComplex_lib.new_cellComplex(p,dim)

^这不起作用,我不知道为什么。

问题2。(此处包含因为问题1 中的瞪眼)我从我的网站返回一个基本上是匿名的指针C代码!这只是感觉,嗯,脏,并且必须有一种更好的方法来返回自定义数据类型并在Python中处理它。为了记录,我非常感谢this stackoverflow answer在那里我学会了这样的巫术 - 但是我不能在晚上睡觉,只要它能够在晚上睡觉。在我的代码中......

1 个答案:

答案 0 :(得分:2)

而不是double **,请使用double [][2]。您将要访问的连续C数组作为指向一行2项的指针进行传递。第一个索引是行索引。

将数组声明为double **是指向double指针的指针,因此p[i]是指针,p[i][0]再次取消引用它。但根据您的数据,p[i]偶然是一个NULL指针。

  

请参阅comp.lang.c FAQ,question 6.18:当我将二维数组传递给期望a的函数时,我的编译器抱怨   指向指针的指针。

对于返回类型,您可以继承c_void_p,或者在ctypes文档中section 15.17.1.7的最后一段使用钩子from_param_as_parameter_