Вбудовування PyPy коду програми на C


На конференції PyGrunn 2016 я виступив з доповіддю про пакет Python cffi та його використання для вбудовування PyPy коду програми на C.

З виходом cffi 1.5.0 та його подальшим включенням в PyPy 5, стає можливим вбудовувати PyPy код. Це робиться шляхом компіляції коду Python у динамічну бібліотеку, яка потім може бути використана в будь-якому іншому мовою. У цій статті я покажу вам, як це робити.

Вбудований API
Перший крок полягає у визначенні інтерфейсу, який визначає, як з додатком на слід викликати наш Python код. Ми повинні вказати це з допомогою прототипів C-функцій. Для нашого прикладу ми розглянемо функцію, яка виконує якісь обчислення, але, звичайно, це може бути все що завгодно.
float compute(float first, float second);

Тепер ми повинні реалізувати ці обчислення на Python:
from my_library import ffi, lib

@ffi.def_extern()
def compute(first, second):
""" Обчислює абсолютна відстань між двома числами. """
return abs(first - second)

Цей фрагмент містить кілька особливих речей для його правильного вбудовування. Перший рядок імпортує об'єкти
ffi
та
lib
з динамічної бібліотеки. Роблячи це реалізація отримує доступ до функцій, що надаються cffi і їх можна використовувати для більш складних завдань, таких як виділення пам'яті. Ім'я
my_library
визначено нижче і відповідає імені нашої динамічної бібліотеки.

Друге, що ми помічаємо в цьому фрагменті — це декоратор
@ffi.def_extern
. Він каже cffi, що декоровані функції повинні бути представлені в публічному API, створюваної C-бібліотеки. Декоровані функції будуть співставлені з прототипами, зазначеними в оголошенні API і їх аргументами і значення, що повертаються будуть перетворюватися автоматично.

Скрипт генерує бібліотеку
Тепер, коли у нас є API і його реалізація, ми повинні насправді куди його прилаштувати. Для цього ми використовуємо скрипт, який генерує динамічну бібліотеку. Він вимагає, щоб два фрагменти коду, наведені вище, перебували у файлах
api.h
та
implementation.py
.
import cffi
ffi = cffi.FFI()

ffi.embedding_api(open("api.h").read())
ffi.embedding_init_code(open("implementation.py").read())

ffi.set_source("my_library", "")
ffi.compile(verbose=True)

Цей скрипт дуже простий. Ми повинні вказати наш API і надати його реалізацію. Вони обидва читаються з диска і відповідають фрагментів коду, наведеним у попередньому розділі.

Після вказівки джерел, ми повинні сказати cffi назва нашої бібліотеки. У цьому прикладі це
my_library
. Крім того, тут є місце для додавання додаткового C-коду, який надає типи заголовкого файлу нашого API, наприклад, за допомогою підключення відповідних заголовних файлів (що не допускається в
embedding_api
). Залишається тільки зібрати вихідні коди, щоб створити файл нашої бібліотеки.

Запуск скрипта виводить деяку інформацію і створює нашу бібліотеку:
$ pypy embed.py
generating ./my_library.c
running build_ext
building 'my_library' extension
...

$ ls my_library.dylib
-rwxr-xr-x 1 djinn staff 9856 May 15 14:46 my_library.dylib

Все що залишилося — це де-небудь її використовувати!

Використовує додаток
Використовувати вбудований Python-код на насправді дуже просто. Це можна зробити за допомогою наступного коду:
#include < stdio.h>
#include "api.h"

int main(void) {
float result = compute(12.34 f, f 10.0);
printf("The result: %f\n", result);

return 0;
}

Як ви бачите, для виклику нашого Python-коду практично нічого не потрібно. Використовуючи API CPython, ви повинні були б запустити інтерпретатор і виконати безліч перетворень параметрів і значення, що повертається. Але не з cffi! Створена бібліотека бере все на себе, так що ви можете зосередитися на дійсно корисної роботи. Останнє, що я повинен показати вам, як це скомпілювати і запустити цей код.
$ clang -o test test.c my_library.dylib

$ ./test
The result: 2.340000

І ось воно! За допомогою всього декількох рядків коду ми написали програму на C, яка запускає інтерпретатор PyPy і виконує наш Python-код, як якщо б це був код на C. Звичайно, я показав вам тільки основи, але це дійсно потужна технологія. Для отримання додаткової інформації, можна подивитися в документацію cffi.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.