ctypes:初始化数组并传递给C函数
ctypes: Initialize array of arrays and pass to C function
我一直在摆弄ctypes,遇到了两个问题:
问题1.我想使用double*
数组构建cellComplex
,但我希望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中处理它。记录在案,我非常感谢这个堆叠式的答案,在那里我学会了这样的魔法——但只要它在我的代码中,我晚上就睡不着了。。。
使用double [][2]
而不是double **
。您正在传递一个连续的C数组,您希望将其作为指向一行2项的指针进行访问。第一个索引是行索引。
将数组声明为double **
是指向double
指针的指针,因此p[i]
是指针,p[i][0]
再次取消引用它。但根据您的数据,p[i]
是一个偶然的NULL
指针。
请参阅comp.lang.cFAQ,问题6.18:当我将一个二维数组传递给一个函数时,我的编译器抱怨道指向指针的指针。
对于返回类型,您可以使用c_void_p
的子类,或者根据ctypes文档中第15.17.1.7节的最后一段使用钩子from_param
和_as_parameter_
。
相关文章:
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 如何在 C++ 中使用它的构造函数初始化 unique_ptrs 的 2D 向量?
- 我们是否需要为 C++ 中的多个函数初始化多个模板?
- 在C++中使用默认构造函数初始化对象的不同方法
- 使用默认构造函数初始化对象的不同方法
- 我们可以用参数化构造函数初始化结构的数组吗?
- 有没有办法使用该类的构造函数初始化另一个类的私有部分内的对象数组?
- 类内初始化与构造函数初始化列表的顺序
- 通过 C++ 中的重载构造函数初始化未知类型的变量
- 使用复制构造函数初始化 new[]
- 如何从子类的构造函数初始化父类的私有成员
- 在构造函数初始化列表中使用 std::variant
- 使用构造函数初始化结构还是在之后设置其值更好?
- C++ 没有匹配的构造函数初始化 []
- 我正在使用dev c ++,但收到错误(C++98'array'必须由构造函数初始化)
- 如何从静态类函数初始化静态类对象
- 使用所述填充构造函数初始化向量中的向量
- 如何同时创建一个具有两个或多个构造函数初始化的对象
- 使用 c++ 中的函数初始化数组
- 使用 lambda 函数初始化静态数据成员