gpt4 book ai didi

python - Py_Initialize 运行需要哪些文件?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:38:11 27 4
gpt4 key购买 nike

我正在编写一段从 C/C++ 应用程序运行 Python 函数的简单代码。为了做到这一点,我设置了 PYTHONPATH 并按如下方式运行初始化:

Py_SetPythonHome("../Python27");
Py_InitializeEx(0);

然后我导入我的模块并运行我的函数。它工作得很好。

我现在正在尝试为我的同事构建一个安装程序来运行我的代码。出于显而易见的原因,我想尽量减少需要包含在此安装程序中的文件数量。

谷歌搜索这个主题告诉我,我应该能够包含文件“Python27.lib”和“Python27.dll”,然后压缩“DLL”和“Lib”文件夹并包含它们。但是,当我尝试这样做时, Py_Initialize 失败了。

快速检查导致此失败的原因表明 Py_Initialize 似乎依赖于 Lib 文件夹中的许多 .pyc 文件,包括(但不限于 warnings.pyc、_abcoll.pyc、_future_.pyc 和“编码”的内容“文件夹。

我不明白为什么会这样。有什么建议吗?

最佳答案

一开始,我想说 Py_InitializeEx 不需要模块(至少不需要非内置模块),所以唯一的要求是 python27.dll(顺便说一句:python27.lib 是 不需要 ,除非你的同事想要链接一些东西 - 但是如果没有 Python 的 Include 目录,这不是很容易)。我有这个代码(使用我使用 VStudio 构建的 Python 2.7.10 10 (2010)):

#include <stdio.h>
#include <conio.h>
#include <Python.h>

int main()
{
int i = 0;
char *pyCode =
"s = \"abc\"\n"
"print s, 1234";
Py_InitializeEx(0);
i = PyRun_SimpleString(pyCode);
Py_Finalize();
printf("PyRun_SimpleString returned: %d\nPress a key to exit...\n", i);
_getch();
return 0;
}
它构建良好,从 VStudio 和命令行运行正常(在将 .dll 复制到其文件夹中之后)。但后来我将 .exe 和 .dll 复制到另一台计算机,运行时, 砰!!!
ImportError: No module named site

考虑到:
  • 我在运行 .exe 的两台机器上的两个控制台中都没有设置 PYTHON* env vars(结果不同)
  • 在两台机器上,Python 安装在同一路径上(我之前(几年前)在无法工作的机器上修改了它)

  • 我不知道为什么它的行为不一样(我没有检查的一件事是机器上可能有一些可以工作的注册表项?)。
    备注 : 网站是位于 下的 (.py(c)) 模块%PYTHON_INSTALL_DIR%\Lib .
    然后,我浏览了 Python 的源代码,发现了 [GitHub]: python/cpython - (v2.7.10) cpython/Python/pythonrun.c (函数 Py_InitializeEx - 当前行 #141 ) - 这是我将如何引用源代码中的一个点):
    if (!Py_NoSiteFlag)
    initsite(); /* Module site */
    而在 初始站点 :
    m = PyImport_ImportModule("site");
    这很明显(Py_NoSiteFlag 是 0 )。
    然后我注意到 Py_NoSiteFlag 被声明为 extern __declspec(dllexport) ( [MS.Docs]: Using extern to Specify Linkage[MS.Docs]: dllexport, dllimport ),所以我将代码修改为:
    #include <stdio.h>
    #include <conio.h>
    #include <Python.h>

    extern __declspec(dllimport) int Py_NoSiteFlag;


    int main()
    {
    int i = 0;
    char *pyCode =
    "s = \"abc\"\n"
    "print s, 1234";
    Py_NoSiteFlag = 1;
    Py_InitializeEx(0);
    i = PyRun_SimpleString(pyCode);
    Py_Finalize();
    printf("PyRun_SimpleString returned: %d\nPress a key to exit...\n", i);
    _getch();
    return 0;
    }
    它有效! 耶!
    因此,此时只需要 .dll 即可运行一段代码。但我想你的代码比那“有点”复杂(它有 import s ( [Python 2.Docs]: The import statement )。要解决导入问题,你可以使用这个不错的模块: [Python 2.Docs]: modulefinder - Find modules used by a script ( Python 2.7 标准模块的一部分)。要使用它:
  • 将您从 C 执行的代码保存在 .py 文件中
  • 对它运行 modulefinder

  • 这是我的代码示例(我的 C 程序中的 pyCode 内容,保存在文件中)。
    代码00.py:
    s = "abc"
    print s, 1234

    运行:
    ${PYTHON_INSTALL_DIR}\python.exe -m modulefinder code00.py

    产量:
    Name                      File
    ---- ----
    m __main__ code00.py

    但是 ,如果我添加一个 import os (这是一个非常常见的模块)文件中的语句,上面的命令产生:
    Name                        File
    ---- ----
    m StringIO %PYTHON_INSTALL_DIR%\lib\StringIO.py
    m UserDict %PYTHON_INSTALL_DIR%\lib\UserDict.py
    m __builtin__
    m __future__ %PYTHON_INSTALL_DIR%\lib\__future__.py
    m __main__ a.py
    m _abcoll %PYTHON_INSTALL_DIR%\lib\_abcoll.py
    m _codecs
    m _collections
    m _functools
    m _hashlib %PYTHON_INSTALL_DIR%\DLLs\_hashlib.pyd
    m _heapq
    m _io
    m _locale
    m _random
    m _sre
    m _struct
    m _subprocess
    m _threading_local %PYTHON_INSTALL_DIR%\lib\_threading_local.py
    m _warnings
    m _weakref
    m _weakrefset %PYTHON_INSTALL_DIR%\lib\_weakrefset.py
    m abc %PYTHON_INSTALL_DIR%\lib\abc.py
    m array
    m atexit %PYTHON_INSTALL_DIR%\lib\atexit.py
    m bdb %PYTHON_INSTALL_DIR%\lib\bdb.py
    m binascii
    m cPickle
    m cStringIO
    m cmd %PYTHON_INSTALL_DIR%\lib\cmd.py
    m codecs %PYTHON_INSTALL_DIR%\lib\codecs.py
    m collections %PYTHON_INSTALL_DIR%\lib\collections.py
    m copy %PYTHON_INSTALL_DIR%\lib\copy.py
    m copy_reg %PYTHON_INSTALL_DIR%\lib\copy_reg.py
    m difflib %PYTHON_INSTALL_DIR%\lib\difflib.py
    m dis %PYTHON_INSTALL_DIR%\lib\dis.py
    m doctest %PYTHON_INSTALL_DIR%\lib\doctest.py
    m dummy_thread %PYTHON_INSTALL_DIR%\lib\dummy_thread.py
    P encodings %PYTHON_INSTALL_DIR%\lib\encodings\__init__.py
    m encodings.aliases %PYTHON_INSTALL_DIR%\lib\encodings\aliases.py
    m errno
    m exceptions
    m fnmatch %PYTHON_INSTALL_DIR%\lib\fnmatch.py
    m functools %PYTHON_INSTALL_DIR%\lib\functools.py
    m gc
    m genericpath %PYTHON_INSTALL_DIR%\lib\genericpath.py
    m getopt %PYTHON_INSTALL_DIR%\lib\getopt.py
    m gettext %PYTHON_INSTALL_DIR%\lib\gettext.py
    m hashlib %PYTHON_INSTALL_DIR%\lib\hashlib.py
    m heapq %PYTHON_INSTALL_DIR%\lib\heapq.py
    m imp
    m inspect %PYTHON_INSTALL_DIR%\lib\inspect.py
    m io %PYTHON_INSTALL_DIR%\lib\io.py
    m itertools
    m keyword %PYTHON_INSTALL_DIR%\lib\keyword.py
    m linecache %PYTHON_INSTALL_DIR%\lib\linecache.py
    m locale %PYTHON_INSTALL_DIR%\lib\locale.py
    P logging %PYTHON_INSTALL_DIR%\lib\logging\__init__.py
    m marshal
    m math
    m msvcrt
    m nt
    m ntpath %PYTHON_INSTALL_DIR%\lib\ntpath.py
    m opcode %PYTHON_INSTALL_DIR%\lib\opcode.py
    m operator
    m optparse %PYTHON_INSTALL_DIR%\lib\optparse.py
    m os %PYTHON_INSTALL_DIR%\lib\os.py
    m os2emxpath %PYTHON_INSTALL_DIR%\lib\os2emxpath.py
    m pdb %PYTHON_INSTALL_DIR%\lib\pdb.py
    m pickle %PYTHON_INSTALL_DIR%\lib\pickle.py
    m posixpath %PYTHON_INSTALL_DIR%\lib\posixpath.py
    m pprint %PYTHON_INSTALL_DIR%\lib\pprint.py
    m random %PYTHON_INSTALL_DIR%\lib\random.py
    m re %PYTHON_INSTALL_DIR%\lib\re.py
    m repr %PYTHON_INSTALL_DIR%\lib\repr.py
    m select %PYTHON_INSTALL_DIR%\DLLs\select.pyd
    m shlex %PYTHON_INSTALL_DIR%\lib\shlex.py
    m signal
    m sre_compile %PYTHON_INSTALL_DIR%\lib\sre_compile.py
    m sre_constants %PYTHON_INSTALL_DIR%\lib\sre_constants.py
    m sre_parse %PYTHON_INSTALL_DIR%\lib\sre_parse.py
    m stat %PYTHON_INSTALL_DIR%\lib\stat.py
    m string %PYTHON_INSTALL_DIR%\lib\string.py
    m strop
    m struct %PYTHON_INSTALL_DIR%\lib\struct.py
    m subprocess %PYTHON_INSTALL_DIR%\lib\subprocess.py
    m sys
    m tempfile %PYTHON_INSTALL_DIR%\lib\tempfile.py
    m textwrap %PYTHON_INSTALL_DIR%\lib\textwrap.py
    m thread
    m threading %PYTHON_INSTALL_DIR%\lib\threading.py
    m time
    m token %PYTHON_INSTALL_DIR%\lib\token.py
    m tokenize %PYTHON_INSTALL_DIR%\lib\tokenize.py
    m traceback %PYTHON_INSTALL_DIR%\lib\traceback.py
    m types %PYTHON_INSTALL_DIR%\lib\types.py
    P unittest %PYTHON_INSTALL_DIR%\lib\unittest\__init__.py
    m unittest.case %PYTHON_INSTALL_DIR%\lib\unittest\case.py
    m unittest.loader %PYTHON_INSTALL_DIR%\lib\unittest\loader.py
    m unittest.main %PYTHON_INSTALL_DIR%\lib\unittest\main.py
    m unittest.result %PYTHON_INSTALL_DIR%\lib\unittest\result.py
    m unittest.runner %PYTHON_INSTALL_DIR%\lib\unittest\runner.py
    m unittest.signals %PYTHON_INSTALL_DIR%\lib\unittest\signals.py
    m unittest.suite %PYTHON_INSTALL_DIR%\lib\unittest\suite.py
    m unittest.util %PYTHON_INSTALL_DIR%\lib\unittest\util.py
    m warnings %PYTHON_INSTALL_DIR%\lib\warnings.py
    m weakref %PYTHON_INSTALL_DIR%\lib\weakref.py

    Missing modules:
    ? _emx_link imported from os
    ? ce imported from os
    ? fcntl imported from subprocess, tempfile
    ? org.python.core imported from copy, pickle
    ? os.path imported from os, shlex
    ? os2 imported from os
    ? posix imported from os
    ? pwd imported from posixpath
    ? readline imported from cmd, pdb
    ? riscos imported from os
    ? riscosenviron imported from os
    ? riscospath imported from os

    正如您所看到的,有非常多的模块(我稍微修改了输出,而不是放置 ${PYTHON_INSTALL_DIR} env var 占位符的实际路径)。为了让 Python 代码正常工作,您必须在安装程序中包含所有这些模块/包。
    备注 关于 modulefinder 的输出(我在玩它时注意到了):
  • 它递归地搜索模块,所以这里是整个模块依赖树
  • 它搜索位于函数中的导入语句(因此,不仅是模块级别的)
  • 没有 搜索动态导入(例如 [Python 2.Docs]: __import__(name[, globals[, locals[, fromlist[, level]]]]) )

  • 因此,查看 os 所需的模块,我不确定从 C 中取出站点导入会产生很大的不同。
    重要提示 :为了确保您的 .exe 可以在任何计算机上运行,​​您可以考虑包含 VStudio C 运行时库或 VCRTLib ( msvcr##(#).dll : [MS.Docs]: Run-Time Library Reference )(其中 *#*s 是占位符对于数字 - 代表 VStudio 版本)在您的安装程序中。

    关于python - Py_Initialize 运行需要哪些文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39539089/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com