Подтвердить что ты не робот

Как я могу создать свои 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. После этого все работало плавно.

4b9b3361

Ответ 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

Однако это не работа для меня.

Мое решение:

  1. установить Anaconda 64bit Python 3.6

  2. установить mingw64

  3. добавить mingw64/bin в PATH
  4. скомпилировать 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
    
  5. загрузить файл 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

Короче:

  1. Убедитесь, что 64-разрядная версия mingw-w64 находится в PATH.
  2. Обезьяна-патч distutils:
    import distutils.cygwinccompiler
    distutils.cygwinccompiler.get_msvcr = lambda: []
    
  3. Некоторые различия в оболочке не спасаются.

  4. extra_link_args = ["-Wl,-Bstatic", "-lpthread"] для статического связывания и отсутствия дополнительных задержек во время выполнения.

  5. pipenv run python setup.py build -c mingw32 теперь работает.