web-dev-qa-db-ja.com

Py_Initializeを実行するにはどのファイルが必要ですか?

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」フォルダの内容。

これがなぜなのか理解できません。何かアドバイス?

5
Matt McC

最初に、Py_InitializeExにはモジュールは必要ない(少なくとも非組み込みは不要)ので、唯一の要件はpython27.dll(btw:python27.libisnotが必要です。ただし、同僚が何かにリンクしたい場合を除きますが、これは非常に簡単ではありませんPython 'sIncludedir)。私はこのコードを持っていました([〜#〜] btw [〜#〜]:私はPython 2.7.10を使用していますVStudio102010))を使用してビルド:

_#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
_

それを考慮して:

  • PYTHON *環境変数が。exeを実行した2台のマシンのどちらのコンソールにも設定されていません(別の結果)
  • 両方のマシンで、Pythonインストールが同じパスにあります(以前(数年前)に、動作しないマシンでそれを変更しました)

なぜ同じように動作しないのかわかりません(確認していないのは、動作するマシンにレジストリキーが存在する可能性があることです)。

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_NoSiteFlagextern __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の標準モジュールの一部)これを利用するには:

  • [〜#〜] c [〜#〜]から実行するコードを。pyファイルに保存します
  • それに対してmodulefinderを実行します

これは、私の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ランタイムライブラリまたはVCRTLibmsvcr ##(# ).dll[MS.Docs]:ランタイムライブラリリファレンス )(whereは数字のプレースホルダーで、インストーラーでVStudioバージョンを表します)。

3
CristiFati