Py_Initialize运行需要哪些文件?
What files are required for Py_Initialize to run?
我正在编写一段简单的代码,从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;
}
它构建良好,它运行OK从VStudio,并从命令行(在复制.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查找
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 [,]]]]))
重要说明:为了确保您的.exe在任何计算机上都能工作,您可以考虑在安装程序中包含VStudio C运行库或VCRTLib (msvcr##(#).dll: [MS.Learn]:运行时库参考)(其中*#*s是数字占位符-表示VStudio版本)。
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 如何将内容数组写入文本文件?
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到