Как собрать всю библиотеку Python (включая зависимости), чтобы ее можно было использовать в C? - PullRequest
0 голосов
/ 04 мая 2018

Как скомпилировать целую библиотеку 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.

1 Ответ

0 голосов
/ 04 мая 2018

Как скомпилировать целую библиотеку 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 или что-то более новое.

...