首页 > 解决方案 > 如何创建一个使用 C 扩展的 Python 库?

问题描述

我的目标是创建一个 Python 库,我可以将它导入到我的任何项目中,并且我希望通过使用 C 语言(类似于 NumPy 的工作方式)使该库更快。

但是,在学习了许多不同的教程和视频之后,我总是遇到同样的错误,并且无法完成教程说我应该能够完成的过程。我一直在关注来自 TutorialsPoint 的本教程:https ://www.tutorialspoint.com/python/python_further_extensions

我试过用谷歌搜索错误,但没有任何价值。

我在我的 PC 上运行 Windows 10 64 位,并且安装了 32 位和 64 位版本的 Python(我认为问题可能与不正确的 Python 版本有关)。我完全按照本教程进行操作,并且完全按照它所说的去做,但是,在安装(构建?)它时,我总是会导致相同的错误结果。

这是我的 C 代码(名为hello.c),它是从教程中复制和粘贴的:

#include <Python.h>

static PyObject* helloworld(PyObject* self) {
   return Py_BuildValue("s", "Hello, Python extensions!!");
}

static char helloworld_docs[] =
   "helloworld( ): Any message you want to put here!!\n";

static PyMethodDef helloworld_funcs[] = {
   {"helloworld", (PyCFunction)helloworld,
      METH_NOARGS, helloworld_docs},
      {NULL}
};

void inithelloworld(void) {
   Py_InitModule3("helloworld", helloworld_funcs,
                  "Extension module example!");
}

这是我的 python setup.py 代码,这也是从教程中复制和粘贴的,尽管我已将目录输入到我的 hello.c 文件中:

from distutils.core import setup, Extension
setup(name='helloworld', version='1.0', ext_modules=[Extension('helloworld', ['C:/Users/penci/OneDrive/Python3.7_64bit/Lib/site-packages/PythonLib/CCode/hello.c'])])

完成此操作并将它们全部保存(在同一个文件中)后,教程说要运行 setup.py 脚本并在其后加上“安装”。在教程中,它说它应该创建所需的 scipts 和数据,并且我应该能够将 python 包导入到我的代码中。但是,当我运行它时,我会得到两件事之一,这取决于我如何运行它。

  1. 我打开命令提示符,运行 setup.py 并在其后安装,就像教程中显示的那样。这种运行程序的方法会给我一个错误代码 1120,或者它会打印出以下内容:

    running install
    running build
    running build_ext
    running install_lib
    copying build\lib.win-amd64-3.7\helloworld.cp37-win_amd64.pyd -> C:\Users\penci\OneDrive\Python3.7_64bit\Lib\site-packages
    running install_egg_info
    Writing C:\Users\penci\OneDrive\Python3.7_64bit\Lib\site-packages\helloworld-1.0-py3.7.egg-info
    

    这就是我认为应该发生的事情,但是,当我尝试将脚本导入我的 python 代码时,它出现在代码建议窗口中,但说“没有名为 helloworld 的模块”(使用 PyCharm 社区)。

  2. 我以管理员身份打开命令提示符,并执行完全相同的操作。当我这样做时,它总是给我相同的结果:

    running install
    running build
    running build_ext
    building 'helloworld' extension
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MT -IC:\Users\penci\OneDrive\Python3.7_64bit\include -IC:\Users\penci\OneDrive\Python3.7_64bit\include "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.7.2\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\cppwinrt" /TcC:/Users/penci/OneDrive/Python3.7_64bit/Lib/site-packages/PythonLib/CCode/hello.c /Fobuild\temp.win-amd64-3.7\Release\Users/penci/OneDrive/Python3.7_64bit/Lib/site-packages/PythonLib/CCode/hello.obj
    hello.c
    C:/Users/penci/OneDrive/Python3.7_64bit/Lib/site-packages/PythonLib/CCode/hello.c(17): warning C4013: 'Py_InitModule3' undefined; assuming extern returning int
    C:\Users\penci\OneDrive\Python3.7_64bit\Lib\site-packages\PythonLib\CCode\hello.c : fatal error C1083: Cannot open compiler generated file: 'C:\Windows\system32\build\temp.win-amd64-3.7\Release\Users\penci\OneDrive\Python3.7_64bit\Lib\site-packages\PythonLib\CCode\hello.obj': No such file or directory
    error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.22.27905\\bin\\HostX86\\x64\\cl.exe' failed with exit status 1
    

(抱歉,代码量很大,我只是不确定哪一点有助于解决问题)

我试过用谷歌搜索“退出状态 1”,但没有出现有意义的结果。

标签: pythoncpython-extensions

解决方案


在您的1观点中,我没有足够的信息来为您提供任何帮助。事实上,即使查看间歇性错误,也会1120显示errlook.exe完全不相关的消息。

在您的2观点中,问题似乎是编译器没有找到Py_InitModule3函数的定义。这导致您没有链接定义该符号的正确 python 库的结论。

无需修改代码或setup.py脚本即可实现正确链接的一种简单方法是定义一个环境变量LIB,Microsoft Windows 链接器cl.exe将通过该环境变量来查找python37.lib库。

SET LIB=%LIB%;C:/Users/penci/OneDrive/Python3.7_64bit/libs

然后您必须setup.py在设置变量的同一控制台中运行脚本。这将解决链接问题,如果没有出现其他问题,这应该允许使用您的自定义模块。


推荐阅读