IPython безусловно очень удобная штука. Быстрая отладка идеи на Python, стабильная и быстрая работа, куча плагинов, делающих эту оболочку просто незаменимой.
Однако в этот раз мне необходимо использовать библиотеку написанную на языке C. А хочу я все это делать в IPython. Конечно, кроме написания C-кода.
Все будет работать в связке с Cython. Язык Cython был создан для получения python-пакетов, работающих также быстро, как-будто они написаны на C/С++ с возможностью написания кода в стиле схожем с Python. Бонусом идет удобная и быстрая возможность обертки C/C++-библиотек для Python.
Примеры реализованы под Linux. При повторении данного примера под Windows необходимо будет сделать предварительную подготовку, установить компилятор MinGW и настроить все пути.
Первым делом определяем директорию и создаем новый блокнот IPython. В эту директорию кладем файл [code]c.c[/code] с кодом на C.
[code c]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <stdlib.h> #include <stdio.h> static char* inside_c(char* s) { int required_size = 100; // Reserve memory for return variable char *r = malloc(sizeof (char) * required_size); // Change string sprintf(r, "we get: %s", s); return r; } |
[/code]
файл c.c, код на C
Далее будем работать в блокноте Ipython и все куски кода вставляем в отдельные ячейки. Включаем cython-магию в ipython.
[code python]
1 |
%cython |
[/code]
ipython, ячейка 1
Создаем файл [code]c_call.pyx[/code] с заголовком функции из C.
[code python]
1 2 3 4 |
%%writefile c_call.pyx cdef extern from "c.c": cpdef char* inside_c(char*) |
[/code]
ipython, ячейка 2
Создаем python-скрипт [code]setup.py[/code] для компиляции библиотеки и заголовочного файла в python-пакет.
[code python]
1 2 3 4 5 6 |
%%writefile setup.py from distutils.core import setup, Extension from Cython.Build import cythonize ext = Extension('c_call', sources = ['c_call.pyx', 'c.c']) setup(name="C Call", ext_modules = cythonize([ext])) |
[/code]
ipython, ячейка 3
Запускаем созданный на предыдущем шаге файл [code]setup.py[/code] для компиляции в текущую директорию C-библиотеки вместе с заголовочным файлом и оберткой от Cython.
[code python]
1 2 3 |
%%bash python setup.py build_ext --inplace |
[/code]
ipython, ячейка 4
Запускаем получившийся винегрет и наслаждаемся.
[code python]
1 2 3 |
import c_call # import pyx-file which has our c-library income = c_call.inside_c(b"from python") # send bytes, not string income # get bytes (char*) |
[/code]
ipython, ячейка 5