Как скомпилировать целую библиотеку Python (включая зависимости), чтобы ее можно было использовать в C?

Как скомпилировать целую библиотеку Python вместе с ее зависимостями, чтобы ее можно было использовать в C (без вызова среды выполнения Python). То есть в скомпилированный код встроен интерпретатор Python, и Python не нужно устанавливать в систему.

Насколько я понимаю, когда код Python скомпилирован с использованием Cython, он:

  • Не вызывает среду выполнения Python, если используется аргумент --embed
  • Компилирует файлы по отдельности
  • Позволяет вызывать различные модули (из среды выполнения Python/других скомпилированных файлов Cython)

Остается неясным вопрос:

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

Упрощенный пример библиотеки Python с именем module, где __init__.py — пустой файл:

module/
├── run.py
├── http/
│   ├── __init__.py
│   ├── http_request.py

http_requests.py содержит:

import requests

def get_ip():
    r = requests.get('https://ipinfo.io/ip')
    print(r.text)

и run.py содержит следующее:

from http import http_request

if __name__ == '__main__':
    http_request.get_ip()

Как вызвать функцию get_ip из C без использования среды выполнения Python (необходимо установить Python при запуске приложения).

Приведенный выше пример очень прост. Фактический вариант использования — сбор/обработка данных робототехники на C с высокой частотой дискретизации. Хотя C отлично подходит для базовой обработки данных, существуют отличные библиотеки Python, которые позволяют проводить гораздо более полный анализ. Цель состоит в том, чтобы вызвать библиотеки Python для данных, которые были частично обработаны в C. Это позволит нам получить гораздо более подробное представление о данных (и обработать их в «реальном времени»). Фреймворки данных слишком велики, чтобы наша команда могла переписать их на C.


person Greg    schedule 04.05.2018    source источник
comment
Связано: Компиляция python в разделяемую библиотеку   -  person metatoaster    schedule 04.05.2018
comment
Что делает ваша библиотека Python? Какие функции, модули и примитивы Python он использует? Покажите, если возможно, какой-нибудь минимально воспроизводимый пример в вашем вопросе. Итак, отредактируйте свой вопрос, чтобы улучшить его.   -  person Basile Starynkevitch    schedule 04.05.2018
comment
@BasileStarynkevitch Я обновил сообщение и включил простой пример библиотеки Python, которую я хотел бы вызывать из C без использования среды выполнения Python.   -  person Greg    schedule 04.05.2018
comment
Вы должны объяснить в своем вопросе, почему именно вы хотите избежать среды выполнения и интерпретатора Python. Вы также должны дать больше контекста и объяснить, что делает ваша библиотека. Без дополнительных пояснений ваш вопрос неясен. Пожалуйста, отредактируйте его снова.   -  person Basile Starynkevitch    schedule 04.05.2018
comment
Для вашего варианта использования это практически невозможно и/или глупо. Почему вы/ваши сотрудники пишете код C для интеграции с этим? Если это будет встроенная система, просто напишите весь код на C и откажитесь от Python. Если это для использования на более высоком уровне, просто напишите все это на Python.   -  person metatoaster    schedule 04.05.2018
comment
@metatoaster Пример только пытался показать концепцию, я обновил сообщение, указав фактический вариант использования.   -  person Greg    schedule 04.05.2018
comment
Самый простой способ состоит в том, чтобы разделить эти два компонента, подключить код C к какому-либо серверу и сбросить вывод (или даже так же просто, как запись в стандартный вывод), а ваш стек Python запускает сервер для получения входных данных для обработки (или так же просто, как читать со стандартного ввода).   -  person metatoaster    schedule 04.05.2018
comment
@BasileStarynkevitch Я включил то, что делает код, и что причина желания избежать среды выполнения Python связана с высокой скоростью выборки / обработки (в реальном времени) данных робототехники.   -  person Greg    schedule 04.05.2018
comment
Это по-прежнему не объясняет и не оправдывает, почему вам нужно избегать Python. Вы можете переписать низкоуровневые слои своего кода на C и оставить Python для более высокоуровневых вещей (и это очень часто делается), возможно, работающих в каком-то другом процессе.   -  person Basile Starynkevitch    schedule 04.05.2018
comment
Ваше заявление или желание избежать Python сильно пахнет какой-то проблемой XY. Я не понимаю, почему вам не нужна среда выполнения Python на вашем компьютере.   -  person Basile Starynkevitch    schedule 04.05.2018
comment
@BasileStarynkevitch Я согласен с вами, и это правильное наблюдение. Чем чаще обрабатываются данные, тем лучше мы можем управлять двигателями (например, балансировать), что приводит к более плавным действиям и меньшему потреблению энергии. Цель состоит в том, чтобы обрабатывать данные как можно чаще, не перестраивая библиотеки с нуля. Раньше мы не пытались соединить Python и C, поэтому компиляция Python в C и использование его в качестве библиотеки кажется подходящим решением.   -  person Greg    schedule 04.05.2018
comment
Я считаю, что вы ошибаетесь — или, по крайней мере, очень наивно — полагая, что компиляция Python в C и использование этого в качестве библиотеки кажется подходящим решением (я думаю, что это неправильный подход). Я думаю, вам лучше оставить Python и продолжать использовать его для высокоуровневых частей.   -  person Basile Starynkevitch    schedule 04.05.2018


Ответы (1)


Как скомпилировать целую библиотеку Python вместе с ее зависимостями, чтобы ее можно было использовать в C (без вызова среды выполнения Python).

Это невозможно вообще. Практически ожидается, что код Python будет работать в интерпретаторе Python.

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

В противном случае (и чаще всего) код C, использующий ваш материал Python, должен встроить интерпретатор Python< /а>.

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

Вы также можете рассмотреть возможность запуска (в своей библиотеке C) некоторого процесса Python (подобного серверу, выполняющего ваши действия Python) и использования межпроцессное взаимодействие, которые зависят от операционной системы. Конечно, Python должен быть установлен в системе приложения, использующего вашу библиотеку. Например, для Linux вы можете разветвить некоторый процесс Python в своей библиотеке и использовать pipe(7) или unix(7) для связи библиотеки C с этим процессом (возможно, с помощью чего-то вроде JSONRPC).

Ваше редактирование (все еще не MCVE) показывает некоторое HTTP-взаимодействие, выполненное в Python. Вы можете сделать это в C с помощью клиентских библиотек HTTP в C, таких как libcurl, или (при необходимости) библиотек HTTP-серверов, таких как libonion.

Поэтому подумайте о том, чтобы переписать свои вещи на C, но с использованием нескольких существующих библиотек C (как и что выбрать — это совсем другой вопрос, вероятно, не по теме в StackOverflow). В противном случае примите зависимости от Python.

Фактический вариант использования — сбор/обработка данных робототехники на C с высокой частотой дискретизации. Хотя C отлично подходит для базовой обработки данных, существуют отличные библиотеки Python, которые позволяют проводить гораздо более полный анализ.

Вы можете оставить высокоуровневые вещи в Python (см. это), но перекодировать низкоуровневые вещи в C, чтобы ускорить их ( многие программы делают это, например, TensorFlow, ...), возможно, как расширения в C для Python или в каком-либо другом процессе. Конечно, это означает некоторые усилия по развитию. Я не думаю, что полностью избегать Python разумно (полностью избавляться от Python нецелесообразно), если вы используете много кода на Python. Кстати, вы могли бы, возможно, рассмотреть возможность встраивания какого-либо другого языка в ваше приложение C (например, Lua, Guile, Ocaml — все они, по слухам, быстрее, чем Python) и оставить Python для более высокого уровня, работающего в каком-то другом процессе.

Вам нужно приложить больше усилий к архитектурному дизайну вашей вещи. Я не уверен, что полностью избегать Python — это разумно. Смешивание Python и C (возможно, при наличии нескольких взаимодействующих процессов) может быть разумнее. Конечно, у вас будут специфичные для операционной системы вещи (особенно на стороне C, для межпроцессного взаимодействия). Если в Linux, прочитайте что-нибудь о системном программировании Linux на C, например. ALP или что-то новее.

person Basile Starynkevitch    schedule 04.05.2018
comment
But not every Python code can be cythonized: Я думал, что, поскольку Cython является расширенным набором Python, весь код Python может быть Cythonized? - person Greg; 04.05.2018
comment
Возможно, вы подумали наивно, но сайт Cython действительно немного оптимистичен... Cython — это надмножество подмножества Python. - person Basile Starynkevitch; 04.05.2018
comment
Я бы поспорил с вашим описанием Cython. Он не совсем совместим, но подавляющее большинство кода Python должно работать без изменений. Он по-прежнему делает это, вызывая libpython, поэтому на самом деле это не перевод на C. - person DavidW; 04.05.2018
comment
@BasileStarynkevitch - ваши утверждения относительно Cython неверны. Фактически, он более совместим с кодом Python, чем сам интерпретатор Python, поскольку он поддерживает весь синтаксис Python от 2.6 до 3.5 и может генерировать для него эквивалентный код C-API. Какой надмножество он может поддерживать или не поддерживать, не имеет значения при обсуждении чистого кода Python. - person danny; 04.05.2018