我将如何创建一个使用 C 扩展的 Python 库?

How would I create a Python library that is extended by using C?

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

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

我尝试用谷歌搜索错误,但没有任何有价值的结果。

我在我的电脑上 运行ning Windows 10 64 位,并且安装了 Python 的 32 位和 64 位版本(我认为问题可能出在某些地方与不正确的 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 脚本,并在其后添加 "install"。在教程中,它说它应该然后创建所需的 scipts 和数据,并且我应该能够将 python 包导入我的代码中。但是,当我 运行 这样做时,我会得到两件事之一,这取决于我如何 运行 它。

  1. 我打开命令提示符,运行 setup.py 然后安装,就像教程中显示的那样。这种 运行ning 程序的方法要么给我一个错误代码 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 代码时,它出现在代码建议 window 中,但说那里是 "no module named helloworld"(使用 PyCharm 社区)。

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

    running install
    running build
    running build_ext
    building 'helloworld' extension
    C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.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 Studio19\Community\VC\Tools\MSVC.22.27905\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.22.27905\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK.7.2\include\um" "-IC:\Program Files (x86)\Windows Kits\include.0.18362.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\include.0.18362.0\shared" "-IC:\Program Files (x86)\Windows Kits\include.0.18362.0\um" "-IC:\Program Files (x86)\Windows Kits\include.0.18362.0\winrt" "-IC:\Program Files (x86)\Windows Kits\include.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
    

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

我尝试用谷歌搜索 "exit status 1",但没有出现任何有意义的结果。

在你的1第一点,我没有足够的信息来给你任何帮助。事实上,即使查看 1120errlook.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 脚本。这将解决链接问题,如果没有其他问题出现,这应该允许使用你的自定义模块。