Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中使用MinGW-w64构建我的C扩展?_Python_C_Compilation_64 Bit - Fatal编程技术网

如何在Python中使用MinGW-w64构建我的C扩展?

如何在Python中使用MinGW-w64构建我的C扩展?,python,c,compilation,64-bit,Python,C,Compilation,64 Bit,因此,我有一些Python C扩展,这些扩展是我之前为运行在Win7中的32位Python构建并使用的。然而,我现在已经切换到64位Python,并且在使用MinGW-w64构建C扩展时遇到了问题 我根据对distutils进行了更改,但我收到一些奇怪的错误,提示出了问题: $ python setup.py build running build running build_ext building 'MyLib' extension c:\MinGW64\bin\x86_64-w64-min

因此,我有一些Python C扩展,这些扩展是我之前为运行在Win7中的32位Python构建并使用的。然而,我现在已经切换到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
。然而,在遵循(倒数第二个)的建议后,我仍然有一个
\uu imp\u Py\u InitModule4\u64
错误。经过一番认真的谷歌搜索之后,我被告知将
Py\u InitModule4
行重命名为
Py\u InitModule4\u 64
的命令绊倒了。在那之后,一切都很顺利。

这对我使用Python 3.3很有效:

  • 从dll创建静态python库

    python dll通常在C:/Windows/System32中;在msys shell中:

    gendef.exe python33.dll
    
    dlltool.exe --dllname python33.dll --def python33.def --output-lib libpython33.a
    
    mv libpython33.a C:/Python33/libs
    
  • 使用swig生成包装器

    e、 例如,
    swig-c++-python myExtension.i

  • 包装器必须使用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、其他SharedLib)都在您的路径中 (windows不使用LD_LIBRARY_PATH或PYTHONPATH)

  • 在Python中,只需:导入myExtension


  • 下面是VC++构建工具的示例代码

    你可以试试:

    python setup.py -c mingw32
    
    然而,这不是我的工作

    我的解决办法是:

  • 安装Anaconda 64位python 3.6

  • 安装

  • 将mingw64/bin添加到路径
  • 通过以下方式从c文件编译dll

    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
    
  • 在.py脚本中加载dll文件

    from ctypes import *  
    m = cdll.LoadLibrary(r"C:\{path_to_dll}\libmypy.dll")  
    print(m.hello())
    

  • 我意识到这是一个老问题,但它仍然是最热门的搜索结果。今天,在2019年,我能够做到这一点:

    简言之:

  • 确保路径中有64位版本的mingw-w64
  • 猴斑区:
    import distutils.cygwinccompiler
    distutils.cygwinccompiler.get_msvcr = lambda: []
    
  • 壳的一些不同之处是w.r.t.逃逸

  • extra_link_args=[“-Wl,-Bstatic”,“-lpthread”]
    以便静态链接,而不具有额外的运行时dep

  • pipenv运行python setup.py build-c mingw32
    现在可以工作了


  • 我用这个线程来学习如何进行C扩展,因为我学到的大部分内容都在其中,所以我想我也应该把最后的发现放在这里,以便其他人在寻找时可以找到它

    我并没有试图编译一些大的东西,只是Hetland开始的Python中的例子。下面是我所做的(示例C pgm被称为palindrome.C)。我正在使用Anaconda和Python3.7,以及MinGW64的TDM-GCC版本。我将使用的所有工具、PYTHONPATH中需要的所有路径以及..\Anaconda3目录放入PYTHON\u HOME中。我仍然在某些事情上使用显式路径

    我创建了libpython37.a库,其中包含上面Mark提到的gendef.exe和dlltool.exe,并将其放入..\Anaconda3\libs中

    我在赫特兰遵循了处方:

    gcc-c回文

    gcc-I$PYTHON\u HOME-I$PYTHON\u HOME/Include-c palindrome\u wrap.c

    第二次失败,编译器找不到Python.h,以下操作正常:

    gcc-I[somedirectories]\Anaconda3\Include-c palindrome_wrap.c

    正如许多人所说,我当时也这么做了,包括赫特兰第三版

    gcc-shared palindrome.o palindrome_wrap.o[somedirectories]/Anaconda3/libs/libpython37.a-o_palindrome.dll

    这不起作用。即使使用了cswu加载库(我在别处也找到了)

    所以我在gendef'd_palindrome.dll中找不到函数,导出中的“is_palindrome”。我浏览了一些SWIG文档,并在%{%}部分和下面声明了函数,这两个函数都是extern,最终得到了回文_wrap.c中的函数extern'd。但是没有导出,所以我回到palindrome.c并重新声明函数为:

    declspec(dllexport)外部整数stdcall是回文(char*text)

    并用回文重新声明。我在上面两处都签了这个签名

    部分成功!当我使用gendef'd_palindrome.dll并使用Load Library调用cswu时,它被列在导出部分。但仍然没有照赫特兰说的做

    导入回文

    在Python中

    再次回到所有的来源,我无法理解这一点。我终于从一开始就开始阅读SWIG文档,不遗余力地在手册中搜索并不能找到找到的地方

    在介绍的最后一节。2.7在样本制作过程中,将其纳入构建系统,其中说明:

    上述示例将生成本地构建文件,如MaMfile、NFALE文件和VisualStudio项目,这些文件将调用SWIG并将生成的C++文件编译成AyExcel。因此(UNIX)或O.Excel。Pyd(Windows)。对于Windows上的其他目标语言,通常会生成DLL,而不是.Pyd文件。 这就是最后一个问题的答案:

    dll的编译步骤应为:

    gcc-shared palindrome.o palindrome\u wrap.o[somedirectories]/Anaconda3/libs/libpython37.a-o\u palindrome.pyd

    (我没有回去更改我的declspec声明,所以我不知道它们是否必要,所以它们仍然存在)

    我有一个文件,_palindrome.pyd

    如果在PYTHONPATH(我的是本地的)工程中,人们可以这样做

    导入回文

    从_回文导入是_回文

    并使用导出、正确包装和打包的C函数