Подключение C-кода в Python с помощью Distutils

В предыдущих постах описаны примеры использования С-библиотек в Python с помощью Cython. Там все было здорово, все работало быстро и без проблем. Единственное, в том случае требуется установить Cython и изучить дополнительно его документацию.

Для быстрого достижения цели, Cython прекрасно себя проявил. Но что делать, если хочется вызывать C-код без установки дополнительных пакетов? Для этого есть несколько возможностей и одна из них, использование distutils — стандартная Python-утилита для сборки и установки пакетов.

Исходные данные:

  • Linux
  • Python 3.5
  • Ipython (Jupyter Notebook)
  • Файл с кодом на C

Создадим директорию, необходимые файлы и новый блокнот:

  • c.c — файл с вызываемой функцией
  • c.h — заголовочный файл
  • cwrap.c — обертка для подключения к Python
  • c.ipynb — блокнот

Код на С

Создадим отдельный файл с функцией.

[code c]

[/code]
файл c.c, код на C

Создадим заголовочный файл для порядка.

[code c]

[/code]
заголовочный файл c.h, код на C

Создадим обертку, где и будем принимать вызов из Python, обрабатывать его и отправлять обратно.

C-function — функция на чистом C, куда передаем строку, меняем ее и возвращаем.
Enter point — функция, где обрабатываем аргументы из Python и вызываем нашу функцию на C.
Array with methods —  массив, где перечисляются все реализованные методы доступные в Python.
Struct — массив с описанием модуля для создания в Python.
Init — функция инициализации модуля в Python.

[code c]

[/code]
файл cwrap.c, код на C

IPython

Теперь все действия в блокноте Ipython, каждый кусок кода вставляем в отдельные ячейки.

Создаем python-скрипт [code]setup_c.py[/code] для компиляции библиотеки в python-пакет.

[code python]

[/code]
ipython, ячейка 1

Запускаем созданный на предыдущем шаге файл [code]setup_c.py[/code] для компиляции в текущую директорию C-библиотеки.

[code python]

[/code]
ipython, ячейка 2

Подключаем модуль, показываем описания модуля и функции. Тестируем.

[code python]

[/code]
ipython, ячейка 3

Репозиторий с кодом.