Инициализация модуля расширения Python - несколько файлов - PullRequest
4 голосов
/ 15 февраля 2011

Создав библиотеку C, состоящую из множества исходных файлов и файлов заголовков, теперь мне нужно обернуть ее слоем Python, чтобы я мог «импортировать» ее.

Я реализовал статический метод, вызываемый из Python, и мне нужно указать, какие методы модуль должен предоставлять интерпретатору.

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

Насколько я могу судить, невозможно вызывать методы в других исходных файлах, если они объявлены как статические в C (пожалуйста, исправьте меня, если я ошибаюсь там), поэтому возможно иметь только один файл C на питон модуль, так как вам разрешен только один нестатический метод в целом.

Это действительно так? Должны ли вы плохо структурировать свой код / ​​нет вообще, если хотите получить к нему доступ из Python?

EDIT:

Итак, в итоге я заработал Cython . Мало того, что переписать интерфейс c / python потребовалось около часа (который раньше занимал около дня из-за всех правил подсчета ссылок и т. Д.), Но он также обрабатывает все проблемы сборки для вас и имеет четкую документацию, описывающую, какие именно методы будут доступны из python.

В частности, главы документации, которые я использовал, были инструкции по сборке , как вызывать библиотеки C , основы языка и как приводить типы, в частности указатели .

Для тех, кто хочет обернуть существующий код C со сложной структурой (то есть что-либо, кроме одного файла) в библиотеку Python, я настоятельно рекомендую Cython.

Ответы [ 3 ]

3 голосов
/ 15 февраля 2011

На самом деле не требуется, чтобы функция инициализации модуля была единственным нестатическим символом в модуле. Это лучшая практика, которая предотвращает загрязнение плоского пространства имен C, используемого для символов времени выполнения. Другим распространенным подходом для этого является размещение специфичного для библиотеки префикса для всех экспортируемых символов. Вы можете сделать и то, и другое, хотя статический подход, как правило, считается более чистым и надежным.

2 голосов
/ 15 февраля 2011

Используйте файл заголовка, чтобы сделать внешние функции доступными для компилятора.Это не проблема, связанная с Python, это общий языковой аспект в C.

my_prototypes.h :

  // declare the prototype. everybody who includes `my_prototypes.h` now knows that it exists.
  PyObject *func_from_other_module(PyObject *self, PyObject *args);

anotherunit.c :

  PyObject *func_from_other_module(PyObject *self, PyObject *args) {
    // actual implementation
  }

mainunit.c :

  #include "my_prototypes.h"

  static PyMethodDef SpamMethods[] = {

    {"func_from_other_module",  func_from_other_module, METH_VARARGS,
      "Blabla"},
    ...
   {NULL, NULL, 0, NULL}        /* Sentinel */
  }

И вы правы, если функция объявлена ​​static, ее можно использовать только изфайл, в котором он содержится. Вам это не нужно - просто оставьте static вне (по сути, вам даже не понадобится заголовок: размещение объявлений функций в верхней части mainunit.c также работает).

0 голосов
/ 22 августа 2015

Итак, в итоге я получил способ использовать Cython .Мало того, что переписать интерфейс c / python потребовалось около часа (который раньше занимал около дня из-за всех правил подсчета ссылок и т. Д.), Но он также обрабатывает все проблемы сборки для вас и имеет четкую документацию, описывающую, какие именнометоды будут доступны из python.

В частности, я использовал следующие главы документации: инструкции по сборке , как вызывать библиотеки C , основы языка и как приводить типы, в частности указатели .

Для тех, кто хочет обернуть существующий сложный структурированный код C (т. Е. Что угодно, кроме одного файла) в библиотеку Python,очень рекомендую Cython.

...