26

そのため、以前にビルドして Win7 で実行されている 32 ビット Python で使用した Python C 拡張機能がいくつかあります。しかし、現在は 64 ビット Python に切り替えており、MinGW-w64 で C 拡張機能をビルドする際に問題が発生しています。

この投稿に従ってdistutilsに変更を加えましたが、何かが間違っていることを示唆する奇妙なエラーが発生しています:

$ python setup.py build
running build
running build_ext
building 'MyLib' extension
c:\MinGW64\bin\x86_64-w64-mingw32-gcc.exe -mdll -O -Wall -Ic:\Python27\lib\site-packages\numpy\core\include -Ic:\Python27\include -Ic:\Python27\PC -c MyLib.c -o build\temp.win-amd64-2.7\Release\mylib.o
MyLib.c: In function 'initMyLib':
MyLib.c:631:5: warning: implicit declaration of function 'Py_InitModule4_64' [-Wimplicit-function-declaration]
writing build\temp.win-amd64-2.7\Release\MyLib.def
c:\MinGW64\bin\x86_64-w64-mingw32-gcc.exe -shared -s build\temp.win-amd64-2.7\Release\mylib.o build\temp.win-amd64-2.7\Release\MyLib.def -Lc:\Python27\libs -Lc:\Python27\PCbuild\amd64 -lpython27 -o build\lib.win-amd64-2.7\MyLib.pyd
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x13d): undefined reference to `__imp_PyExc_ValueError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1275): undefined reference to `__imp_PyExc_ValueError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1eef): undefined reference to `__imp_PyExc_ImportError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1f38): undefined reference to `__imp_PyExc_AttributeError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1f4d): undefined reference to `__imp_PyCObject_Type'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1f61): undefined reference to `__imp_PyExc_RuntimeError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1fc7): undefined reference to `__imp_PyExc_RuntimeError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1ffe): undefined reference to `__imp_PyExc_RuntimeError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x2042): undefined reference to `__imp_PyExc_RuntimeError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x206c): undefined reference to `__imp_PyExc_RuntimeError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x208a): more undefined references to `__imp_PyExc_RuntimeError' follow
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x20a7): undefined reference to `__imp_PyExc_ImportError'
collect2.exe: error: ld returned 1 exit status
error: command 'x86_64-w64-mingw32-gcc' failed with exit status 1

情報を見つけるためにかなりグーグルで検索しましたが、明確な答えを見つけるのは簡単ではありません. 誰かがこれに光を当てることができますか?Win7 で 64 ビット Python 用の C 拡張機能を正常にビルドできるようにするには、さらにどのような変更を行う必要がありますか?

編集:

以下のcgohlkeのコメントにいくつかの役立つポインタがあった後、なんとか生成できましたlibpython27.aただし、この投稿(最後から 2 番目)のアドバイスに従った後でも、__imp_Py_InitModule4_64エラーが発生しました。いくつかの深刻なGoogle-fuの後、私はなんとかこの投稿Py_InitModule4につまずいて、行の名前をに変更するように指示しましたPy_InitModule4_64。その後、すべてが順調に機能しました。

4

5 に答える 5

15

これはPython 3.3でうまくいきました:

  1. dllから静的python libを作成する

    python dll は通常 C:/Windows/System32 にあります。msys シェルで:

    gendef.exe python33.dll
    
    dlltool.exe --dllname python33.dll --def python33.def --output-lib libpython33.a
    
    mv libpython33.a C:/Python33/libs
    
  2. swig を使用してラッパーを生成する

    例えば、 swig -c++ -python myExtension.i

  3. ラッパーは MS_WIN64 でコンパイルする必要があります。そうしないと、Python でクラスをインポートするときにコンピューターがクラッシュします。

    g++ -c myExtension.cpp -I/other/includes
    
    g++ -DMS_WIN64 -c myExtension_wrap.cxx -IC:/Python33/include
    
  4. 共有ライブラリ

    g++ -shared -o _myExtension.pyd myExtension.o myExtension_wrap.o -lPython33 -lOtherSharedLibs -LC:/Python33/libs -LC:/path/to/other/shared/libs
    
  5. すべての共有ライブラリ (gdal、OtherSharedLibs) が PATH にあることを確認します (Windows は LD_LIBRARY_PATH または PYTHONPATH を使用しません)。

  6. Python では、単に: import myExtension

出来上がり!

于 2013-04-03T19:38:20.187 に答える
-1

私はこのスレッドを使用して、C 拡張機能の作成方法を学習しました。私が学んだことのほとんどはそこにあるので、他の誰かが探している場合に見つけられるように、最終的な発見もここに置くと思いました。

私は何か大きなものをコンパイルしようとしていたのではなく、Hetland の Beginning Python の例にすぎません。これが私がしたことです (例の C pgm は palindrome.c と呼ばれます)。私は、Python 3.7 を含む Anaconda と MinGW64 の TDM-GCC バージョンを使用しています。使用するすべてのツールをパスに入れ、必要なすべてのパスを PYTHONPATH に入れ、..\Anaconda3 ディレクトリを PYTHON_HOME に入れます。私はまだいくつかのものに明示的なパスを使用することになりました。

マークが上で言ったように、gendef.exe と dlltool.exe で libpython37.a ライブラリを作成し、..\Anaconda3\libs に配置しました。

私は Hetland の処方箋に従いました。

gcc -c 回文.c

gcc -I$PYTHON_HOME -I$PYTHON_HOME/Include -c palindrome_wrap.c

2 番目は失敗し、コンパイラは Python.h を見つけることができませんでした。次のように動作しました。

gcc -I[いくつかのディレクトリ]\Anaconda3\Include -c palindrome_wrap.c

その後、Hetland 3rd ed. を含む多くの人が言ったように、

gcc -shared palindrome.o palindrome_wrap.o [いくつかのディレクトリ]/Anaconda3/libs/libpython37.a -o _palindrome.dll

これはうまくいきませんでした。Load Library cswu を使用しても (他の場所でも見つけました)。

そのため、_palindrome.dll を gendef しましたが、エクスポートに "is_palindrome" という関数が見つかりませんでした。私はいくつかの SWIG ドキュメントを調べ、%{ %} セクションとその下の両方で関数を宣言し、両方とも extern を宣言しました。しかしエクスポートがないので、palindrome.c に戻り、関数を次のように再宣言しました。

declspec(dllexport) extern int __stdcall is_palindrome(char* text)

この署名を使用して、上記の両方の場所で palindrome.i で再宣言します。

部分成功!_palindrome.dll を gendef したときにエクスポート セクションにリストされ、Load Library を使用して cswu の呼び出しを行うことができました。しかし、それでもヘトランドの言うことと実行することは実行しません

import _palindrome

パイソンで。

もう一度すべてのソースに戻って、これを理解できませんでした。私は最終的に SWIG のドキュメントを最初から読み始めました。

イントロダクションセクションの終わりに。2.7ビルドシステムへの組み込み、サンプルのMakeプロセスの下で、次のように述べています。

「上記の例では、makefile、nmake ファイル、Visual Studio プロジェクトなどのネイティブ ビルド ファイルが生成され、SWIG が呼び出され、生成された C++ ファイルが _example.so (UNIX) または _example.pyd (Windows) にコンパイルされます。Windows 上の他のターゲット言語の場合通常、.pyd ファイルではなく dll が生成されます。」

これが最後の問題の答えです。

dll のコンパイル手順は次のようになります。

gcc -shared palindrome.o palindrome_wrap.o [いくつかのディレクトリ]/Anaconda3/libs/libpython37.a -o _palindrome.pyd

(戻ってdeclspec宣言を変更しなかったので、それらが必要かどうかわからないので、それらもまだそこにありました)。

ファイル _palindrome.pyd を取得しました

PYTHONPATH (私の場合はローカル) が機能する場合、次のことができます。

import _palindrome

from _palindrome インポート is_palindrome

そして、TDM-GCC でコンパイルされた、エクスポートされ、適切にラップおよびパッケージ化された C 関数を、約束どおり Python で使用します。別のインストールの MinGW64 である gcc は、.pyd ファイルの処理方法を認識しています。dll と pyd は同じバイト長だったので比較しました。それらは何百もの点で同じではありません。

これが他の誰かに役立つことを願っています。

于 2020-03-26T14:30:41.827 に答える