Py_Initialize运行需要哪些文件?

What files are required for Py_Initialize to run?

本文关键字:文件 Initialize 运行 Py      更新时间:2023-10-16

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

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

然后导入模块并运行函数。

我现在正在尝试为我的同事构建一个安装程序来运行我的代码。我想要最小化我需要包含在这个安装程序中的文件数量,原因很明显。

在主题周围搜索告诉我,我应该能够包含文件"Python27. net"。lib"answers"Python27.dll",然后压缩" dll"answers" lib"文件夹并包含它们。然而,当我尝试这样做时,Py_Initialize失败了。

快速检查导致此失败的原因显示Py_Initialize似乎依赖于Lib文件夹中的许多.pyc文件,包括(但不限于)警告。pyc , _abcoll。pyc , _future_。Pyc 和"encodings"文件夹的内容。

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

一开始,我想说Py_InitializeEx不需要模块(至少没有非内置模块),所以唯一的要求是python27.dll (BTW: python27。lib不是必需的,除非你的同事想链接一些东西来反对它——但这不是很容易(em>w/o Python s Includedir)。
我有这个代码(使用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: %dnPress a key to exit...n", i);
    _getch();
    return 0;
}

它构建良好,它运行OKVStudio,并从命令行(在复制.dll在其文件夹)。但是后来我把.exe.dll复制到另一台计算机上,当运行时,砰!!

ImportError: No module named site
考虑:

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

  • 在两台机器上,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 */

initsite:

m = PyImport_ImportModule("site");

这是显而易见的( Py_NoSiteFlag 0 )。

然后我注意到Py_NoSiteFlag被声明为extern __declspec(dllexport) ([MS.Learn]: Using extern to Specify Linkage, [MS.Learn]: 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: %dnPress a key to exit...n", i);
    _getch();
    return 0;
}

,它工作!耶!

因此,此时只需要.dll来运行一段代码。但是我想象你的代码是"有点"。更复杂的是(它有imports [Python 2。:导入语句)。要解决import的问题,你可以使用这个不错的模块:modulefinder -查找脚本使用的模块(Python 2.7标准模块的一部分)。使用它:
  • 保存从C执行的代码到.py文件

  • 运行modulefinder查找

下面是我的代码示例(pyCode contents in my C program,保存在文件中)。

code00.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%libStringIO.py
m UserDict                  %PYTHON_INSTALL_DIR%libUserDict.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%libabc.py
m array
m atexit                    %PYTHON_INSTALL_DIR%libatexit.py
m bdb                       %PYTHON_INSTALL_DIR%libbdb.py
m binascii
m cPickle
m cStringIO
m cmd                       %PYTHON_INSTALL_DIR%libcmd.py
m codecs                    %PYTHON_INSTALL_DIR%libcodecs.py
m collections               %PYTHON_INSTALL_DIR%libcollections.py
m copy                      %PYTHON_INSTALL_DIR%libcopy.py
m copy_reg                  %PYTHON_INSTALL_DIR%libcopy_reg.py
m difflib                   %PYTHON_INSTALL_DIR%libdifflib.py
m dis                       %PYTHON_INSTALL_DIR%libdis.py
m doctest                   %PYTHON_INSTALL_DIR%libdoctest.py
m dummy_thread              %PYTHON_INSTALL_DIR%libdummy_thread.py
P encodings                 %PYTHON_INSTALL_DIR%libencodings__init__.py
m encodings.aliases         %PYTHON_INSTALL_DIR%libencodingsaliases.py
m errno
m exceptions
m fnmatch                   %PYTHON_INSTALL_DIR%libfnmatch.py
m functools                 %PYTHON_INSTALL_DIR%libfunctools.py
m gc
m genericpath               %PYTHON_INSTALL_DIR%libgenericpath.py
m getopt                    %PYTHON_INSTALL_DIR%libgetopt.py
m gettext                   %PYTHON_INSTALL_DIR%libgettext.py
m hashlib                   %PYTHON_INSTALL_DIR%libhashlib.py
m heapq                     %PYTHON_INSTALL_DIR%libheapq.py
m imp
m inspect                   %PYTHON_INSTALL_DIR%libinspect.py
m io                        %PYTHON_INSTALL_DIR%libio.py
m itertools
m keyword                   %PYTHON_INSTALL_DIR%libkeyword.py
m linecache                 %PYTHON_INSTALL_DIR%liblinecache.py
m locale                    %PYTHON_INSTALL_DIR%liblocale.py
P logging                   %PYTHON_INSTALL_DIR%liblogging__init__.py
m marshal
m math
m msvcrt
m nt
m ntpath                    %PYTHON_INSTALL_DIR%libntpath.py
m opcode                    %PYTHON_INSTALL_DIR%libopcode.py
m operator
m optparse                  %PYTHON_INSTALL_DIR%liboptparse.py
m os                        %PYTHON_INSTALL_DIR%libos.py
m os2emxpath                %PYTHON_INSTALL_DIR%libos2emxpath.py
m pdb                       %PYTHON_INSTALL_DIR%libpdb.py
m pickle                    %PYTHON_INSTALL_DIR%libpickle.py
m posixpath                 %PYTHON_INSTALL_DIR%libposixpath.py
m pprint                    %PYTHON_INSTALL_DIR%libpprint.py
m random                    %PYTHON_INSTALL_DIR%librandom.py
m re                        %PYTHON_INSTALL_DIR%libre.py
m repr                      %PYTHON_INSTALL_DIR%librepr.py
m select                    %PYTHON_INSTALL_DIR%DLLsselect.pyd
m shlex                     %PYTHON_INSTALL_DIR%libshlex.py
m signal
m sre_compile               %PYTHON_INSTALL_DIR%libsre_compile.py
m sre_constants             %PYTHON_INSTALL_DIR%libsre_constants.py
m sre_parse                 %PYTHON_INSTALL_DIR%libsre_parse.py
m stat                      %PYTHON_INSTALL_DIR%libstat.py
m string                    %PYTHON_INSTALL_DIR%libstring.py
m strop
m struct                    %PYTHON_INSTALL_DIR%libstruct.py
m subprocess                %PYTHON_INSTALL_DIR%libsubprocess.py
m sys
m tempfile                  %PYTHON_INSTALL_DIR%libtempfile.py
m textwrap                  %PYTHON_INSTALL_DIR%libtextwrap.py
m thread
m threading                 %PYTHON_INSTALL_DIR%libthreading.py
m time
m token                     %PYTHON_INSTALL_DIR%libtoken.py
m tokenize                  %PYTHON_INSTALL_DIR%libtokenize.py
m traceback                 %PYTHON_INSTALL_DIR%libtraceback.py
m types                     %PYTHON_INSTALL_DIR%libtypes.py
P unittest                  %PYTHON_INSTALL_DIR%libunittest__init__.py
m unittest.case             %PYTHON_INSTALL_DIR%libunittestcase.py
m unittest.loader           %PYTHON_INSTALL_DIR%libunittestloader.py
m unittest.main             %PYTHON_INSTALL_DIR%libunittestmain.py
m unittest.result           %PYTHON_INSTALL_DIR%libunittestresult.py
m unittest.runner           %PYTHON_INSTALL_DIR%libunittestrunner.py
m unittest.signals          %PYTHON_INSTALL_DIR%libunittestsignals.py
m unittest.suite            %PYTHON_INSTALL_DIR%libunittestsuite.py
m unittest.util             %PYTHON_INSTALL_DIR%libunittestutil.py
m warnings                  %PYTHON_INSTALL_DIR%libwarnings.py
m weakref                   %PYTHON_INSTALL_DIR%libweakref.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的输出(我在玩它的时候注意到了):

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

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

  • 搜索动态导入s(例如[Python 2]。文档:__import__(名称[,全局[,当地人[,fromlist [,]]]]))

因此,看看os所需的模块,我不确定从C中取出站点导入是否会产生很大的差异。

重要说明:为了确保您的.exe在任何计算机上都能工作,您可以考虑在安装程序中包含VStudio C运行库VCRTLib (msvcr##(#).dll: [MS.Learn]:运行时库参考)(其中*#*s是数字占位符-表示VStudio版本)。