Как я могу создать свои C-расширения с помощью MinGW-w64 в Python?
Итак, у меня есть несколько расширений Python C, которые я ранее создал и использовал в 32-разрядном Python, запущенном в Win7. Теперь я переключился на 64-битный Python, и у меня возникают проблемы с расширением C с помощью MinGW-w64.
Я внес изменения в 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
Я искал немного информации, чтобы найти информацию, но нелегко найти определенный ответ. Может ли кто-то пролить свет на это? Какие дальнейшие изменения я должен сделать, чтобы иметь возможность успешно создавать C-расширения для 64-битного Python в Win7?
EDIT:
После некоторых полезных указателей в комментариях cgohlke ниже мне удалось создать libpython27.a
. Однако после того, как я посоветовал этот пост (от 2-го до последнего), у меня все еще была ошибка __imp_Py_InitModule4_64
. После некоторого серьезного Google-fu мне удалось переместиться через этот пост, чтобы мне переписать строку Py_InitModule4
на Py_InitModule4_64
. После этого все работало плавно.
Ответы
Ответ 1
Это сработало для меня с Python 3.3:
-
создать статический python lib из dll
dll python обычно находится в 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
-
использовать swig для создания оберток
например, swig -c++ -python myExtension.i
-
wrapper ДОЛЖЕН быть скомпилирован с помощью MS_WIN64, или ваш компьютер будет сбой при импорте класса в Python
g++ -c myExtension.cpp -I/other/includes
g++ -DMS_WIN64 -c myExtension_wrap.cxx -IC:/Python33/include
-
общая библиотека
g++ -shared -o _myExtension.pyd myExtension.o myExtension_wrap.o -lPython33 -lOtherSharedLibs -LC:/Python33/libs -LC:/path/to/other/shared/libs
-
убедитесь, что все общие библиотеки (gdal, OtherSharedLibs) находятся в вашем PATH
(окна не используют LD_LIBRARY_PATH или PYTHONPATH)
-
в Python, просто: import myExtension
вуаля!
Ответ 2
Вот пример кода для VC++ инструментов сборки https://github.com/starnight/python-c-extension/tree/master/00-HelloWorld
Вы можете попробовать:
python setup.py -c mingw32
Однако это не работа для меня.
Мое решение:
-
установить Anaconda 64bit Python 3.6
-
установить mingw64
- добавить mingw64/bin в PATH
-
скомпилировать dll из файла c
gcc -c libmypy.c -IC:\Users\{user_name}\Anaconda3\pkgs\python-3.6.4-h6538335_1\include
gcc -shared -o libmypy.dll libmypy.o -LC:\Users\{user_name}\Anaconda3\pkgs\python-3.6.4-h6538335_1\libs -lPython36
-
загрузить файл DLL в .py скрипт
from ctypes import *
m = cdll.LoadLibrary(r"C:\{path_to_dll}\libmypy.dll")
print(m.hello())
Ответ 3
Я понимаю, что это старый вопрос, но это по-прежнему лучший результат поиска. Сегодня, в 2019 году, я смог сделать это:
https://github.com/PetterS/quickjs/commit/67bc2428b8c0716538b4583f4f2b0a2a5a49106c
Короче:
- Убедитесь, что 64-разрядная версия mingw-w64 находится в PATH.
- Обезьяна-патч distutils:
import distutils.cygwinccompiler
distutils.cygwinccompiler.get_msvcr = lambda: []
-
Некоторые различия в оболочке не спасаются.
-
extra_link_args = ["-Wl,-Bstatic", "-lpthread"]
для статического связывания и отсутствия дополнительных задержек во время выполнения.
-
pipenv run python setup.py build -c mingw32
теперь работает.