C/C++アプリケーションからPython関数を実行する簡単なコードを作成しています。これを行うために、PYTHONPATHを設定し、次のように初期化を実行します。
Py_SetPythonHome("../Python27");
Py_InitializeEx(0);
次に、モジュールをインポートして関数を実行します。それは素晴らしい働きをします。
私は今、同僚が私のコードを実行するためのインストーラーを構築しようとしています。明らかな理由により、このインストーラーに含める必要があるファイルの数を最小限にしたいと思います。
件名をグーグルで検索すると、「Python27.lib」と「Python27.dll」のファイルを含め、「DLL」と「Lib」フォルダをZipして含めることができるはずです。ただし、これを試行すると、Py_Initializeが失敗します。
この失敗の原因を簡単に調べると、Py_InitializeはLibフォルダー内の多数の.pycファイルに依存しているように見えます(ただし、これに限定されませんwarnings.pyc、_ abcoll.pyc、_ future_.pycおよび「encodings」フォルダの内容。
これがなぜなのか理解できません。何かアドバイス?
最初に、Py_InitializeExにはモジュールは必要ない(少なくとも非組み込みは不要)ので、唯一の要件はpython27.dll(btw:python27.libisnotが必要です。ただし、同僚が何かにリンクしたい場合を除きますが、これは非常に簡単ではありませんPython 'sIncludedir)。私はこのコードを持っていました([〜#〜] btw [〜#〜]:私はPython 2.7.10を使用していますVStudio10(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を別のコンピューターにコピーし、実行中にbang! !!
_ImportError: No module named site
_
それを考慮して:
なぜ同じように動作しないのかわかりません(確認していないのは、動作するマシンにレジストリキーが存在する可能性があることです)。
注:siteis a(。py(c))%PYTHON_INSTALL_DIR%\ Libにあるモジュール。
次に、Pythonのソースコードを参照し、これに遭遇しました(ファイル:pythonrun.c、行:269、関数Py_InitializeExまたはpythonrun.c:269:Py_InitializeEx-これは、ソースコード内のポイントを参照する方法です):
_ if (!Py_NoSiteFlag)
initsite(); /* Module site */
_
pythonrun.c:727:initsite:
_ m = PyImport_ImportModule("site");
_
これはかなり明白です(Py_NoSiteFlagは0です)。
次に、Py_NoSiteFlagがextern __declspec(dllexport)
として宣言されていることに気付きました( [MS.Docs]:externを使用してリンケージを指定 、 [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]:importステートメント )importの問題を解決するには、次のNiceモジュールを使用できます: [Python 2.Docs]:modulefinder-スクリプトが使用するモジュールを検索 (Python 2.7の標準モジュールの一部)これを利用するには:
これは、私のpyCodeの内容の例です[〜#〜] c [〜#〜]プログラムに保存され、ファイル)。
code.py:
_s = "abc"
print s, 1234
_
ランニング:
_%PYTHON_INSTALL_DIR%\python -m modulefinder code.py
_
利回り:
_Name File ---- ---- m __main__ code.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コードを機能させるには、これらのモジュール/パッケージをすべてインストーラーに含める必要があります。
Notesmodulefinderの出力(私がそれを遊んでいるときに気づいた)について:
したがって、osに必要なモジュールを見て、siteインポートを[〜#〜] c [〜#〜]は大きな違いをもたらします。
重要な注意:。exeがどのコンピューターでも機能することを確認するには、VStudio CランタイムライブラリまたはVCRTLib(msvcr ##(# ).dll: [MS.Docs]:ランタイムライブラリリファレンス )(where#は数字のプレースホルダーで、インストーラーでVStudioバージョンを表します)。