龙空技术网

教你创建 Python的 C语言 扩展

杨同学编程 406

前言:

如今我们对“python调用c语言”可能比较关注,同学们都需要学习一些“python调用c语言”的相关文章。那么小编也在网络上汇集了一些关于“python调用c语言””的相关资讯,希望你们能喜欢,同学们一起来学习一下吧!

在本教程中,我们将了解如何使用C编程语言创建一个非常简单的 Python 模块。我觉得这是一个很好的话题,因为我个人很难找到有效的简洁文档并向我展示了基础知识。

为什么需要 C 扩展?

C在 Python 语言成为瓶颈的情况下,能够编写扩展程序会派上用场。有时您需要低级语言的原始性能,例如C为了减少响应时间和处理时间等。

基本要求

在本教程中,我们将构建一个非常简单的C基于 Python 的模块,该模块将具有许多不同的功能,希望这些功能足以让您入门。

我们将创建 2 个不同的函数:

一个Hello World简单地执行打印的函数。一个接收值的简单斐波那契函数n。入门

让我们深入研究C代码。打开.c将包含新模块的文件并添加#include <Python.h>到顶部。这将引入必要的CPython 对象,使我们能够构建我们的模块。

#include <Python.h>// Function 1: A simple 'hello world' functionstatic PyObject* helloworld(PyObject* self, PyObject* args){    printf("Hello World\n");    return Py_None;}// Our Module's Function Definition struct// We require this `NULL` to signal the end of our method// definitionstatic PyMethodDef myMethods[] = {    { "helloworld", helloworld, METH_NOARGS, "Prints Hello World" },    { NULL, NULL, 0, NULL }};// Our Module Definition structstatic struct PyModuleDef myModule = {    PyModuleDef_HEAD_INIT,    "myModule",    "Test Module",    -1,    myMethods};// Initializes our module using our above structPyMODINIT_FUNC PyInit_myModule(void){    return PyModule_Create(&myModule);}
我们的 setup.py 文件

值得庆幸的是,Python 包含一些使语言扩展更容易的模块。在这里,我们可以指定我们模块的名称并传入.c组成我们模块的必要文件。

from distutils.core import setup, Extensionsetup(name = 'myModule', version = '1.0',  \   ext_modules = [Extension('myModule', ['test.c'])])
构建和安装我们的模块

为了build和install我们新创建的C模块,我们必须执行以下操作:

python setup.py buildpython setup.py install

连续运行时,您应该看到以下输出。然后我们可以启动我们的 Python 解释器并调用我们新创建的模块:

 $ python3.6 setup.py buildrunning buildrunning build_extbuilding 'myModule' extension/usr/bin/clang -fno-strict-aliasing -Wsign-compare -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -arch i386 -arch x86_64 -g -I/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -c test.c -o build/temp.macosx-10.6-intel-3.6/test.o/usr/bin/clang -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -g build/temp.macosx-10.6-intel-3.6/test.o -o build/lib.macosx-10.6-intel-3.6/myModule.cpython-36m-darwin.so $ python3.6 setup.py installrunning installrunning buildrunning build_extrunning install_libcopying build/lib.macosx-10.6-intel-3.6/myModule.cpython-36m-darwin.so -> /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packagesrunning install_egg_infoRemoving /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/myModule-1.0-py3.6.egg-infoWriting /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/myModule-1.0-py3.6.egg-info $ python3.6Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> import myModule>>> myModule.helloworld()Hello World>>>
我们的斐波那契函数

现在让我们看一个更复杂的函数,它接收一个值n ,然后返回适当的斐波那契数。我们不会在memoization这里做任何花哨的事情,它将是一个普通的旧递归函数,具有糟糕的性能。然而,它将向我们展示如何在我们的C模块中接收一个值并返回一个值。

// Function 2: A C fibonacci implementation// this is nothing special and looks exactly// like a normal C version of fibonacci would lookint Cfib(int n){    if (n < 2)        return n;    else        return Cfib(n-1)+Cfib(n-2);}// Our Python binding to our C function// This will take one and only one non-keyword argumentstatic PyObject* fib(PyObject* self, PyObject* args){    // instantiate our `n` value    int n;    // if our `n` value    if(!PyArg_ParseTuple(args, "i", &n))        return NULL;    // return our computed fib number    return Py_BuildValue("i", Cfib(n));}

同样,我们应该像以前一样构建和安装它。然后我们可以像这样测试它:

>>> import myModule>>> myModule.fib(2)1
结论

希望您发现本教程很有用,它阐明了创建您自己的C基于模块的过程。如果您想留下一些反馈或提出其他问题,请随时在下面的评论部分中。

标签: #python调用c语言