Python ctypes函数指针

4

我创建了一个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
我认为我已经成功地通过以下代码传递了结构体sys*指针:
class sys(Structure):
    _fields_ = [("alpha", c_double),
                ("sigma", c_double)]

然后在那里使用POINTER(sys)作为argtype。最后,gsl_rng是来自GNU Scientific Library的典型随机数生成器; 我不知道从哪里开始。

有人可以给我解释一下复杂的ctypes吗?

1个回答

1
在ctypes中,像这样的函数指针类型似乎介于不存在和未记录之间,但仍然可以使用。关键是不要定义argtypes

来自ctypes文档

函数对象…默认情况下接受任意数量的参数,接受任何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

当然,如果您真的希望像ctypes在指定argtypes时为您执行的类型检查,那么这并不能帮助您。我不知道有什么方法可以同时拥有这个“蛋糕”并将其食用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接