Встраивание 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.

Если вам нужно только передать несколько строк назад и вперед, это тривиально, но если вы хотите очень тесную интеграцию, то вам, вероятно, понадобится несколько из них:

Единственный исполняемый файл

Если у вас не может быть установщика, и вы действительно не хотите иметь кучу.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 запустить все остальные сценарии.

Другие вопросы по тегам