Встраивание Python в C++
Если этот вопрос можно сформулировать лучше / его нужно разбить на множество вопросов, пожалуйста, предупредите меня
Мне нужно упаковать скрипты Python для того, чтобы отправлять их как одиночные исполняемые файлы (в идеале) или как одиночные исполняемые файлы с поддержкой файлов (не в идеале).
Я видел py2app и py2exe. Они не соответствуют моим требованиям, так как я ищу единственный способ сделать это, и в будущем может потребоваться взаимодействие упакованных скриптов с исполняемым файлом, из которого они запускаются.
Каков наилучший способ сделать это? Сценарии, которые я буду встраивать, могут даже требовать нескольких файлов, что, я уверен, усложняет ситуацию.
Если бы я хотел использовать в будущем интерпретатор, отличный от CPython (т. Е. PyPy или Stackless), будет ли этот процесс отличаться (кроме вызовов API в исполняемом файле C++)?
Нужно ли устанавливать Python на компьютеры, на которых будет работать пакет, или встраивание Python означает, что он полностью встроен? Я видел на Python Wiki что-то о Py_SetPythonHome()
, что указывало бы на то, что для этого нужно установить Python (или, по крайней мере, его библиотеки). Я прав?
3 ответа
PyInstaller с --onefile
опция поместит все в один файл, хотя для запуска потребуется немного больше времени. Боюсь, что он не совместим с PyPy, но не должно быть так сложно заставить его работать с использованием Stackless.
Удачи!
Да, ты можешь!
Самый простой с новейшим Python3 <OS> <arch> embeddable zip file
, который содержит.so /.dll и все модули.
Инструкции здесь: https://docs.python.org/3/extending/embedding.html
#include <Python.h>
int
main(int argc, char *argv[])
{
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
Py_SetProgramName(program); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is', ctime(time()))\n");
Py_Finalize();
PyMem_RawFree(program);
return 0;
}
Более сложная часть - это связь между вашим кодом C++ и кодом Python.
Если вам нужно только передать несколько строк назад и вперед, это тривиально, но если вы хотите очень тесную интеграцию, то вам, вероятно, понадобится несколько из них:
- создать модуль Python в (C++ code, C ABI) и внедрить его - это означает, что Python сможет работать
import yourmod; yourmod.yourfunc(...)
который будет запускать ваш пользовательский код C++ и / или - разрешить и вызвать функции Python из C++ (обратное) /questions/35021006/vyizov-metoda-python-iz-cc-i-izvlechenie-ego-vozvraschaemogo-znacheniya/35021041#35021041
Единственный исполняемый файл
Если у вас не может быть установщика, и вы действительно не хотите иметь кучу.DLL/.so/etc, это описано, например, здесь Объединить DLL в EXE? и это специфично для ABI, для Windows, другого Linux и т. д. будет один путь, и вам, возможно, придется переопределить механизм импорта Python (чтобы он не искал dll / so в файловой системе) - на данный момент Вы также можете использовать PyInstaller или расширить / объединить PyInstaller со своим приложением. Пожалуйста, изучите https://github.com/pyinstaller/pyinstaller/tree/develop/bootloader/src и оцените, насколько это сложно
PyPy
Простое встраивание возможно http://doc.pypy.org/en/latest/embedding.html но встраивание в один файл - нет. Вы можете взломать исходный код PyPy и создать собственный встраиваемый объект, но вы будете первым, кто сделает это:)
Stackless
Должно быть так же просто, как обычный CPythion
Вы уверены, что вам нужно встраивать файлы Python?
Я спрашиваю, потому что вы упоминаете, что хотите упаковать файлы Python как отдельные исполняемые файлы. Не могли бы вы установить Python на целевой машине, и поскольку скрипты Python являются исполняемыми файлами сами по себе, вам нужно только что-то, чтобы их запустить. Мастер Python скрипт может запустить все остальные скрипты.
В противном случае вы должны посмотреть в C++, что может запустить скрипт Python. Затем попросите главный сценарий Python запустить все остальные сценарии.