Вызов функций C в Python

У меня есть куча функций, которые я написал на C, и мне нужен код, написанный на Python, чтобы иметь доступ к этим функциям.

Я прочитал несколько вопросов здесь, которые касаются подобной проблемы ( здесь и здесь, например), но я смущен тем, какой подход мне нужно принять.

Один вопрос рекомендует ctypes, а другой рекомендует cython. Я прочитал немного документации для обоих, и я совершенно не понимаю, о чем я буду работать лучше для меня.

В принципе, я написал код python для выполнения двухмерных БПФ, и мне бы хотелось, чтобы код C смог увидеть этот результат, а затем обработать его через различные функции C, которые я написал. Я не знаю, будет ли мне легче называть Python с C или наоборот.

Если я хорошо понимаю, у вас нет предпочтения диалогизировать как c => python или как python => c. В таком случае я бы рекомендовал Cython . Он довольно открыт для многих видов манипуляций, особенно в вашем случае, вызывая функцию, написанную на Python с C.

Вот как это работает ( public api ):

В следующем примере предполагается, что у вас есть класс Python ( self – его экземпляр) и что этот класс имеет метод ( method имени), который вы хотите вызвать в этом классе, и обработать результат (здесь double ) из C Эта функция, написанная в Cython extension , поможет вам выполнить этот вызов.

 cdef public api double cy_call_func_double(object self, char* method, bint *error): if (hasattr(self, method)): error[0] = 0 return getattr(self, method)(); else: error[0] = 1 

На стороне C вы сможете выполнить вызов следующим образом:

 PyObject *py_obj = .... ... if (py_obj) { int error; double result; result = cy_call_func_double(py_obj, (char*)"initSimulation", &error); cout << "Do something with the result : " << result << endl; } 

Где PyObject – это struct предоставляемая API Python / C. После того, как вы поймали py_obj (путем каста регулярного object python, в вашем расширении cython, например: <PyObject *>my_python_object ), вы, наконец, сможете вызвать на initSimulation метод initSimulation и сделать что-то с результатом. (Здесь double , но Cython легко справляется с vectors , sets , … )

Ну, я знаю, что то, что я только что написал, может сбивать с толку, если вы никогда ничего не писали, используя Cython , но он должен быть короткой демонстрацией многочисленных вещей, которые он может сделать для вас в период слияния .

С другой стороны, этот подход может занять больше времени, чем перекодировать ваш код Python на C, в зависимости от сложности ваших алгоритмов. На мой взгляд, инвестирование времени в изучение Cython уместно только в том случае, если вы планируете часто получать такие потребности …

Надеюсь, это было хотя бы информативным …

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

  1. Напишите функции C, которые вы хотите использовать. (Вы, наверное, сделали это уже)
  2. Создайте общий объект (.so, для linux, os x и т. Д.) Или динамически загружаемую библиотеку (DLL, для Windows) для этих функций. (Возможно, вы уже это сделали)
  3. Напишите оболочку ctypes (это проще, чем кажется, я написал для этого инструкцию )
  4. Вызовите функцию из этой оболочки в Python. (Это так же просто, как вызов любой другой функции python)

Будет проще вызвать C из python. Ваш сценарий звучит странно – обычно люди пишут большую часть кода на питоне, за исключением части, насыщенной процессором, которая написана на C. Является ли двумерный FFT вычислительно-интенсивной частью вашего кода?

Ну, здесь вы имеете в виду две вещи ниже.

  1. Как вызвать функцию c внутри из python (Расширение python)
  2. Как вызвать функцию / скрипт python из C-программы (Embedding Python)

Для # 2, который является «Встраивание Python»

Вы можете использовать сегмент кода ниже:

 #include "python.h" int main(int argc, char *argv[]) { Py_SetProgramName(argv[0]); /* optional but recommended */ Py_Initialize(); PyRun_SimpleString("from time import time,ctime\n" "print 'Today is',ctime(time())\n"); /*Or if you want to run python file within from the C code*/ //pyRun_SimpleFile("Filename"); Py_Finalize(); return 0; } 

Для # 1, который является «Расширением Python». Лучше всего было бы использовать Ctypes (btw portable по всему варианту python).

из импорта ctypes *

libc = cdll.msvcrt

print libc.time (Нет)

1438069008

printf = libc.printf

printf («Привет,% s \ n», «Мир!»)

Привет мир! 14

printf («% d бутылок пива \ n», 42)

42 бутылки пива 19

Для подробного руководства вы можете обратиться к моей статье в блоге :