簡體   English   中英

嵌入 Python 的 C++:如果未安裝 Python,則崩潰

[英]C++ with Python embedding: crash if Python not installed

我在 Windows 上開發,我到處搜索都沒有找到任何人談論這種事情。

我在我的桌面上制作了一個 C++ 應用程序,它使用 MSVC 嵌入了 Python 3.1。 我鏈接了 python31.lib 並將 python31.dll 與可執行文件一起包含在應用程序的運行文件夾中。 效果很好。 我的擴展和嵌入代碼絕對有效並且沒有崩潰。

我將運行文件夾發送給未安裝 Python 的朋友,應用程序在腳本設置階段為他崩潰了。

幾個小時前,我在安裝了 Python 2.6的筆記本電腦上試用了該應用程序。 我得到了和我朋友一樣的崩潰行為,通過調試發現是 Py_Initialize() 調用失敗了。

我在我的筆記本電腦上安裝了 Python 3.1,但沒有更改應用程序代碼。 我運行它並且運行完美。 我卸載了 Python 3.1,應用程序再次崩潰。 我在我的應用程序中放入代碼以從本地 python31.dll 動態鏈接,以確保它正在使用它,但我仍然遇到崩潰。

我不知道解釋器需要的不僅僅是 DLL 來啟動還是什么。 我一直無法找到這方面的任何資源。 Python 文檔和其他指南似乎從未解決過如何分發使用 Python 嵌入的 C/C++ 應用程序,而無需用戶在本地安裝 Python。 我知道這在 Windows 上比在 Unix 上更嚴重,但我已經看到許多在本地嵌入 Python 的 Windows C/C++ 應用程序,但我不確定它們是如何做到的。

除了 DLL,我還需要什么? 為什么我安裝 Python 時它可以工作,然后當我卸載它時它就停止工作了? 聽起來應該如此微不足道; 也許這就是為什么沒有人真正談論它的原因。 不過,我真的無法解釋如何處理這個崩潰問題。

非常感謝你提前。

除了 pythonxy.dll 之外,您還需要整個 Python 庫,即 lib 文件夾的內容,加上擴展模塊,即 DLLs 文件夾的內容。 沒有標准庫,Python 甚至無法啟動,因為它試圖找到 os.py(在 3.x 中;string.py 在 2.x 中)。 在啟動時,它會導入一些模塊,特別是 site.py。

它在不同的位置搜索標准庫; 在您的情況下,它最終會在注冊表中找到它。 之前,使用可執行文件名稱(通過 Py_SetProgramName 設置)試圖找到地標; 它還會檢查文件 python31.zip,該文件應該是標准庫的壓縮副本。 它還檢查環境變量 PYTHONHOME。

您可以自由地從庫中刪除不需要的東西; 有多種工具可以靜態計算依賴關系(尤其是 modulefinder)。

如果你想盡量減少文件的數量,你可以

  1. 將所有擴展模塊靜態鏈接到您的 pythonxy.dll,甚至將 pythonxy.dll 靜態鏈接到您的應用程序
  2. 使用凍結工具; 這將允許將標准庫的字節碼鏈接到您的 pythonxy.dll 中。
  3. (替代 2.)使用 pythonxy.zip 作為標准庫。

好的。 如果您不想壓縮,請將 Python26\DLLs & Python26\lib 復制到您的 exe 目錄,如下所示:

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

然后使用 Py_SetPythonHome() API 設置 PYTHONHOME。 顯然,此 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;
}

很好,搜索路徑是相對於 exe 的。 Py_GetPath 可以告訴你它在哪里尋找模塊。

我想為可能仍然遇到問題的其他人添加一些額外的信息,就像我一樣。 我最終能夠使用用戶 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)。

我通過從http://www.microsoft.com/en-us/download/details.aspx?id=29下載、安裝和運行“vcredist_x86.exe”包解決了這個問題。 我認為,雖然我不確定,但您至少需要在 Win7 上這樣做,而不是像過去那樣簡單地將 MSVC*90.DLL 放在 your.exe 旁邊。 微軟安裝程序在 Win7 下以特殊方式放置文件並注冊它們。

我也嘗試了 .zip 文件方法,但沒有用,即使安裝了 MSVCR90.DLL。

Python 標准庫的壓縮包適用於 Python27。

我壓縮了 Lib 和 dll 的內容,並確保沒有額外的 python27-subfolder 或 Lib 或 dll 子文件夾。 即只是一個名為 python27.zip 的 zip 包含所有文件。

我復制了那個 zip 和 python27.dll 以及可執行文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM