我创建了一个包含许多函数的C库,我可以使用ctypes从python调用它们。我已经了解了一些较简单的问题,但我对如何将正确的参数传递给以下函数感到困惑:
foo(double *, double *, void(*f1)(double *, double *, double, struct sys *),
void(*f2)(double *, double *, double, struct sys *), struct sys *, double *,
double, double, int, int, gsl_rng *)
我的出发点是为函数设置.argtypes
。我有用POINTER(100*c_double)
等分类的双数组。
但是,我仍然坚持如何传递函数指针。我有许多函数(f1和f2的形式),它们与foo
位于同一个库中,我希望将它作为参数传递给foo
。
我认为我已经通过使用以下代码传递了struct sys *指针ok:
class sys(Structure):
_fields_ = [("alpha", c_double),
("sigma", c_double)]
然后使用POINTER(sys)
作为argtype
。最后,gsl_rng
是GNU科学图书馆的典型随机数生成器;我不知道从哪里开始。
任何人都能对复杂的ctypes有所了解吗?
答案 0 :(得分:1)
ctypes中的这样的函数指针类型似乎介于不存在和未文档之间,但您仍然可以使用它们。关键是根本不定义argtypes 。
函数对象...默认接受任意数量的参数,接受任何ctypes数据实例作为参数,...
因此,只要我们不指定argtypes,我们应该能够将指针堵塞在那里并希望最好,并且这种方法实际上是有效的。这是一个简单的工作示例:
F.C:
int f(int n, int (*h)(int)){ return (*h)(n); }
int g(int n){ return n+1; }
f.py:
import ctypes
so = ctypes.CDLL('/path/to/f.so')
f = so.f
g = so.g
print(f(3, g))
输出:
$ gcc -o f.so -shared -fPIC f.c
$ python f.py
4
当然,如果您真的希望在指定argtypes时ctypes为您执行的类型检查,那么这对您没有帮助。我不知道有任何方法可以吃那个特别的蛋糕并且吃它。