2014-07-29 3 views
3

Я создал C-библиотеку с рядом функций, которые я могу вызвать из python с использованием ctypes. Я получил мою голову вокруг некоторых из более простых, но я озадачен тем, как я передаю правильные аргументы следующей функции:Python ctypes function pointer

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; Я не знаю, с чего начать.

Может ли кто-нибудь осветить сложный ctypes?

ответ

1

Типы указателей функций, подобные этому в ctypes, кажутся где-то между несуществующими и недокументированными, но вы все равно можете их использовать. Ключ не определять типы argtypes вообще.

От ctypes documentation:

Функциональные объекты ... по умолчанию принимает любое количество аргументов, принимать любые ctypes экземпляры данных в качестве аргументов, ...

Ergo, мы должны быть способный просто затормозить указатели там и надеяться на лучшее, пока мы не укажем типы argtypes, и этот подход действительно работает. Вот простой рабочий пример:

Ь:

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, тогда это вам не поможет. Я не знаю, как можно получить этот торт и съесть его.