Подтвердить что ты не робот

С++ с вложением Python: сбой, если Python не установлен

Я развиваюсь в Windows, и я искал везде, не найдя никого, кто говорил об этом.

Я сделал приложение С++ на своем рабочем столе, в которое встроен Python 3.1 с помощью MSVC. Я связал python31.lib и включил python31.dll в папку запуска приложения вместе с исполняемым файлом. Он отлично работает. Мой код расширения и встраивания определенно работает, и сбоев нет.

Я отправил папку запуска моему другу, у которого нет Python, и приложение врезается для него во время этапа настройки сценариев.

Несколько часов назад я попробовал приложение на своем ноутбуке с установленным Python 2.6. У меня такое же поведение при столкновении, как и у моего друга, и через отладку выяснилось, что это был вызов Py_Initialize(), который терпит неудачу.

Я установил Python 3.1 на свой ноутбук без изменения кода приложения. Я побежал, и он работает отлично. Я удалил Python 3.1, и приложение снова сработало. Я добавил код в свое приложение, чтобы динамически связать его с локальной python31.dll, чтобы убедиться, что он его использует, но я все равно получаю сбой.

Я не знаю, требуется ли интерпретатору больше, чем DLL для запуска или что. Я не смог найти никаких ресурсов на этом. Документация на Python и другие руководства, похоже, никогда не рассматривают, как распространять ваши приложения на C/С++, которые используют вложение Python, не устанавливая локально локальный Python. Я знаю, что это больше проблема в Windows, чем в Unix, но я видел несколько приложений Windows C/С++, которые встраивают Python локально, и я не уверен, как они это делают.

Что еще мне нужно, кроме DLL? Почему это работает, когда я устанавливаю Python и перестаю работать, когда я его удалю? Похоже, это должно быть так тривиально; может быть, поэтому никто не говорит об этом. Тем не менее, я не могу объяснить, как справиться с этой проблемой.

Спасибо вам заблаговременно.

4b9b3361

Ответ 1

В дополнение к pythonxy.dll вам также нужна вся библиотека Python, то есть содержимое папки lib, а также модули расширения, то есть содержимое папки DLL. Без стандартной библиотеки Python даже не запустится, так как он пытается найти os.py(в 3.x; string.py в 2.x). При запуске он импортирует несколько модулей, в частности site.py.

Существуют различные местоположения, где он ищет стандартную библиотеку; в ваших случаях он в конечном итоге находит это в реестре. Прежде чем использовать имя исполняемого файла (как установлено через Py_SetProgramName), пытаясь найти ориентир; он также проверяет файл python31.zip, который должен быть зашифрованной копией стандартной библиотеки. Он также проверяет переменную окружения PYTHONHOME.

Вы можете лишить библиотеку вещи, которые вам не нужны; существуют различные инструменты, которые вычисляют зависимости статически (особенно в модуле).

Если вы хотите свести к минимуму количество файлов, вы можете

  • связывать все модули расширения статически с вашим pythonxy.dll или даже связывать pythonxy.dll статически в ваше приложение
  • используйте инструмент замораживания; это позволит связать байтовый код стандартной библиотеки с вашим pythonxy.dll.
  • (альтернативно, 2.) используйте pythonxy.zip для стандартной библиотеки.

Ответ 2

Ницца. И если вы не хотите zip, скопируйте Python26\DLLs и Python26\lib в каталог exe как:

.\myexe.exe       
.\python26.dll
.\Python26\DLLs
.\Python26\lib

И затем установите PYTHONHOME с помощью API Py_SetPythonHome(). По-видимому, этот API не входит в список "разрешенных" вызовов до Py_Initialize();

Ниже работал у меня в Windows (Python не установлен):

#include "stdafx.h"
#include <iostream>
#include "Python.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
   char pySearchPath[] = "Python26";
   Py_SetPythonHome(pySearchPath);
   Py_Initialize();
   PyRun_SimpleString("from time import time,ctime\n"
                     "print 'Today is',ctime(time())\n");
   //cerr << Py_GetPath() << endl;
   Py_Finalize();

    return 0;
}

Хорошо, что путь поиска относительный w.r.t exe. Py_GetPath может показать вам, где все это ищет модули.

Ответ 3

Я хотел добавить дополнительную информацию для других, у которых все еще могут быть проблемы с этим, как и я. В конечном итоге я смог получить свое приложение, используя метод, предложенный пользователем sambha, то есть:

Program Files (x86)\
    MyApplicationFolder\
        MyApplication.exe
        python27.dll
        Python27\
            DLLs\ (contents of DLLs folder)
            Lib\ (contents of Lib folder)

... с одним важным : мне также нужно установить MSVCR90.DLL. Я использую Python 2.7 и, видимо, python27.dll требует MSVCR90.DLL(и, возможно, другие MSVC * 90.DLL).

Я решил это путем загрузки, установки и запуска пакета 'vcredist_x86.exe' из http://www.microsoft.com/en-us/download/details.aspx?id=29. Я думаю, хотя я не уверен, что вам нужно сделать это таким образом, по крайней мере, на Win7, а не просто разместить MSVC * 90.DLL вместе с вашим .exe, как вы, возможно, уже в прошлом. Установщик Microsoft помещает файлы и регистрирует их особым образом под Win7.

Я также пробовал использовать .zip файл, но это не сработало, даже если установлен MSVCR90.DLL.

Ответ 4

Для меня с Python27 работал zip стандартной библиотеки Python.

Я закрепил содержимое Lib и dll и убедился, что вложенную папку python27-sub или lib или dll нет. то есть просто zip с именем python27.zip, содержащий все файлы.

Я скопировал этот zip и python27.dll вместе с исполняемым файлом.