Py_Initialize 运行需要哪些文件?

2024-03-04

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

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

然后我导入我的模块并运行我的函数。效果很好。

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

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

快速检查导致此失败的原因表明 Py_Initialize 似乎依赖于 Lib 文件夹中的许多 .pyc 文件,包括(但不限于)警告.pyc, _abcoll.pyc, _future_.pyc以及“encodings”文件夹的内容。

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


一开始我想说不需要任何模块(至少不需要非内置的一)对于Py_InitializeEx,所以唯一的要求是python27.dll (BTW: python27.lib is not必需的,除非你的同事想要链接一些东西 - 但这并不容易w / o Python's Include dir).
我有这段代码(使用Python 2.7.10我用它构建的VStudio 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;
}

它构建得很好,运行起来OK from VStudio,并从命令行(复制后.dll在其文件夹中)。但后来我复制了.exe and .dll到另一台计算机并在运行时,bang!!!

ImportError: No module named site

考虑到:

  • 我没有PYTHON* env vars我运行的两台机器上的任何一个控制台都没有设置.exe(结果不同)

  • 在两台机器上Python安装位于同一路径上(我之前(几年前)在不起作用的机器上修改了它)

我不知道为什么它的行为不一样(我没有检查的一件事是机器上可能有一些注册表项可以工作?)。

Note: site is a (.py(c)) 模块位于%PYTHON_INSTALL_DIR%\Lib.

然后,我浏览了Python的源代码,我遇到了[GitHub]: python/cpython - (v2.7.10) cpython/Python/pythonrun.c https://github.com/python/cpython/blob/main/Python/pythonrun.c(功能Py_InitializeEx- 当前线路#141) - 这就是我将如何引用源代码中的一点):

if (!Py_NoSiteFlag)
    initsite(); /* Module site */

而在initsite:

m = PyImport_ImportModule("site");

这是非常明显的(Py_NoSiteFlag is 0).

然后我注意到Py_NoSiteFlag被声明为extern __declspec(dllexport) ([MS.Learn]:使用 extern 指定链接 https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/0603949d(v=vs.100), [MS.Learn]:dllexport、dllimport https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/3y1sfaz2(v=vs.100)),所以我将代码修改为:

#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;
}

它有效!Yay!

所以,此时只有.dll是运行一段代码所必需的。但我想你的代码比这“有点”复杂(它有imports ([Python 2.Docs]:导入语句 https://docs.python.org/2.0/ref/import.html)。为了解决import问题,你可以使用这个不错的模块:[Python 2.Docs]: modulefinder - 查找脚本使用的模块 https://docs.python.org/2/library/modulefinder.html?highlight=modulefinder#module-modulefinder(部分Python 2.7的标准模块)。要使用它:

  • 保存您执行的代码C in a .py file

  • Run 模块查找器反对

这是我的代码的示例(pyCode我的内容C程序,保存在文件中)。

代码00.py:

s = "abc"
print(s, 1234)

Running:

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

yields:

Name                      File
----                      ----
m __main__                code00.py

But,如果我添加一个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代码要工作,您必须在安装程序中包含所有这些模块/包。

Notes about 模块查找器的输出(我在玩它时注意到的):

  • 它递归地搜索模块,所以这是整个模块依赖树

  • 它搜索import位于函数中的语句(因此,不仅仅是模块级别的语句)

  • It doesn't搜索动态imports (e.g. [Python 2.Docs]: __import__(name[ globals[ locals[ fromlist[ level]]]]) https://docs.python.org/2/library/functions.html#__import__)

因此,查看所需的模块os,我不确定取出site进口于C,有很大的不同。

重要的提示: 为了确保你的.exe适用于任何计算机,您可以考虑包括VStudio C 运行时库 or VCRTLib (msvcr##(#).dll: [MS.Learn]:运行时库参考 https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/59ey50w6(v=vs.100)) (其中 *#*s 是数字占位符 - 代表VStudio版本)在您的安装程序中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Py_Initialize 运行需要哪些文件? 的相关文章

  • 调度算法,找到设定长度的所有非重叠区间

    我需要为我的管理应用程序实现一种算法 该算法将告诉我何时可以将任务分配给哪个用户 我实现了一个蛮力解决方案 它似乎有效 但我想知道是否有更有效的方法来做到这一点 为了简单起见 我重写了算法以对数字列表进行操作 而不是数据库查询等 下面我将尝
  • .NET 是否有相当于 Python 中的 **kwargs 的功能?

    我一直无法通过典型渠道找到这个问题的答案 在Python中我可以有以下函数定义 def do the needful kwargs Kwargs is now a dictionary i e do the needful spam 42
  • Keras CNN 回归模型损失低,准确度为 0

    我在 keras 中遇到这个 NN 回归模型的问题 我正在研究一个汽车数据集 以根据 13 个维度预测价格 简而言之 我已将其读取为 pandas 数据帧 将数值转换为浮点数 缩放值 然后对分类值使用 one hot 编码 这创建了很多新列
  • 如何在 django-rest-framework 查询集响应中添加注释数据?

    我正在为查询集中的每个项目生成聚合 def get queryset self from django db models import Count queryset Book objects annotate Count authors
  • 使用 C 通过引用传递数组

    是的 我已经阅读了这个问题和答案 在 C 中通过引用传递数组 https stackoverflow com questions 1106957 pass array by reference in c 我有一个类似的问题 并从该问题中实现
  • 如何用C语言创建字典?

    我正在用 C 语言编写一个微控制器 作为它的一部分 我想在 7 段显示器上显示某些字母 每个字母都有一个对应的数字 使 7 段显示屏显示该字母 它没有真正的模式 因为数字只是通过将显示字母所需的 7 段显示器上的位相加而成 因此如果我可以创
  • 如何在C#中使用默认浏览器打开带有锚点(#)的html文件

    我正在尝试在 C 中打开上下文帮助文件 当我没有指定锚点时 它工作得很好 Process Start C Help Help htm 但是当我指定锚点时 它不会打开 Process Start C Help Help htm Toc3420
  • Django model.foreignKey 并返回 self.text 错误

    所以我正在 Django 中处理 model py 但遇到了 2 个 pylint 错误 我不明白为什么 这是 pylint 的问题还是我在代码中做错了什么 E1120 No value for argument on delete in
  • 寻找自定义 SynchronizationContext 的示例(单元测试所需)

    我需要定制同步上下文 http msdn microsoft com en us library system threading synchronizationcontext aspx that 拥有一个运行 Posts 和 Sends
  • 黑屏只是闪烁一会儿

    在我的 Windows Phone 8 应用程序中 我有一个搜索页面 其中有一个文本框供用户输入搜索关键字 输入默认SIP键盘的 Enter 键时将调用搜索 搜索结果显示在另一个页面中 为了在导航到结果页面之前隐藏键盘 我使用 this F
  • 如何在 Windows 10 上将 ipynb 文件与 Jupyter Lab(来自 Anaconda)关联

    我使用 Windows 10 Jupiter Lab 是从 Anaconda 安装的 我想交往ipynb使用 Jupyter Lab 保存文件 这样 当我双击ipynb文件应使用 Jupyter Lab 打开 我该怎么做 Install n
  • C# 从字符串变量中获取类型并在泛型方法中使用它

    我希望能够通过某种方式 即从数据库 获取我收到的字符串值的实际类型 这样我就可以在通用方法中使用该类型 例如DoSomething
  • Web Api 2 在 OWIN 中间件中获取控制器和操作名称?

    如何在自定义 OWIN 中间件中检索 api 控制器名称和 api 操作名称 我可以在消息处理程序内部执行此操作 如下所示 var config request GetConfiguration var routeData config R
  • MonoMac 窗口关闭时没有错误

    我刚刚开始在 Xamarin Studio 中使用 MonoMac 并且遇到了最奇怪的问题 我有一个带有 NSButton 和 NSTextField 的窗口 至此 我已经删除了按钮上的事件处理程序 因此它不会执行任何操作 除了在单击它时突
  • timeval_subtract 解释

    使用 timeval subtract 函数来查找两个 struct timeval 类型之间经过的时间 有人可以解释一下用于 通过更新 y 执行后续减法的进位 和其他部分的目的和逐步数学吗 我了解该函数的目的以及如何在程序中实现它 但我想
  • Linq 表达式树 Any() 问题

    您好 我在使用 Any 扩展方法的表达式树时遇到问题 这是我的代码 IQueryable
  • 如何获取 (Linux) 机器的 IP 地址?

    这个问题和之前问的几乎一样如何获取本地计算机的IP地址 https stackoverflow com questions 122208 get the ip address of local computer 问题 但是我需要找到一个的I
  • Python 3d 金字塔

    我是 3D 绘图新手 我只想用 5 个点建造一个金字塔并通过它切出一个平面 我的问题是我不知道如何填充两侧 points np array 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 fig plt figure ax fi
  • 为什么删除void*是UB而不是编译错误?

    为什么要通过删除对象void 是未定义的行为 而不是编译错误 void foo void p delete p 这段代码编译并生成代码 尽管有关于 gcc 和 clang 的警告 令人惊讶的是 ICC 没有给出警告 2 5 warning
  • printf 右对齐括号内的数字

    我正在编写一个程序 显示数组中的所有信息 它必须以括号中的数组索引开头 例如 2 并且它们必须彼此正确对齐 如果只是数字 我知道你可以这样做 printf 10d index 但是用括号括起来会得到以下输出 1 2 10 11 当我真正希望

随机推荐