Python的C/C++扩展——Python的C语言接口

简介: Python语言最初是用C语言实现的一种脚本语言,后来被称为CPython,是因为后来又有其它语言实现的Python,比如Python实现的Python——PyPy,Java语言实现的Python——Jython,.Net实现的Python——IronPython。

Python语言最初是用C语言实现的一种脚本语言,后来被称为CPython,是因为后来又有其它语言实现的Python,比如Python实现的Python——PyPy,Java语言实现的Python——Jython,.Net实现的Python——IronPython。
23e4b95b0fa64f202e3dfa0052519c170d0

CPython具有优良的开放性和可扩展性,并提供了方便灵活的应用程序接口(API),从而使得C/C++程序员能够在各个级别上对Python解释器的功能进行扩展。

Python的C语言接口很适合封装C语言实现的各种函数,如果要封装C++的类,使用boost_python或者SWIG更方便和合适。

1 模块封装

假设我们有一个C函数:

/* 文件名: mylib.c */
int addone(int a) {
    return a+1;
}

如果想在Python解释器中调用该函数,则应该首先将其实现为Python中的一个模块,这需要编写相应的封装接口,如下所示:

/* wrap_mylib.c */
#include <Python.h>
#include "mylib.h"
PyObject* wrap_addone(PyObject* self, PyObject* args) 
{
  int n, result;

  if (! PyArg_ParseTuple(args, "i:fact", &n))
    return NULL;
  result = addone(n); /*这里调用C函数 */
  return Py_BuildValue("i", result);
}
static PyMethodDef mylibMethods[] = 
{
  {"addone", wrap_addone, METH_VARARGS, "Add one to N"},
  {NULL, NULL}
};
void initmylib() 
{
  PyObject* m;
  m = Py_InitModule("mylib", mylibMethods);
}

上面就是一个典型的Python扩展模块,它至少应该包含三个部分:

导出函数:wrap_addone();
方法列表:mylibMethods[];
初始化函数: initmylib()

2 导出函数

要在Python解释器中调用C语言中的某个函数,首先要为它编写对应的导出函数,上述例子中的导出函数为wrap_addone。在Python的C语言扩展中,所有的导出函数都具有相同的函数原型:

PyObject wrap_method(PyObject self, PyObject* args);
这个函数是Python解释器和C函数进行交互的接口,一般以wrap_开头后面跟上C语言的函数名,这样命名把导出函数和C语言函数对应起来使得代码更加清晰。它带有两个参数:self和args。

参数self 只在C函数被实现为内联方法(built-in method)时才被用到,通常该参数的值为空(NULL)。
参数args 中包含了Python解释器要传递给C函数的所有参数,通常使用Python的C语言扩展接口提供的函数PyArg_ParseTuple()来获得这些参数值。

所有的导出函数都返回一个PyObject指针,如果对应的C函数没有真正的返回值(即返回值类型为void),则应返回一个全局的None对象(Py_None),并将其引用计数增1,如下所示:

PyObject* wrap_method(PyObject *self, PyObject *args) 
{
  Py_INCREF(Py_None);
  return Py_None;
}

3 方法列表

方法列表中列出了所有可以被Python解释器使用的方法,上述例子对应的方法列表为:

static PyMethodDef mylibMethods[] = 
{
  {"addone", wrap_addone, METH_VARARGS, "Add one to N"},
  {NULL, NULL}
};

方法列表中的每项由四个部分组成:

  • 方法名
    导出函数

参数传递方式
方法描述

方法名是从Python解释器中调用该方法时所使用的名字。
参数传递方式则规定了Python向C函数传递参数的具体形式,可选的两种方式是METH_VARARGS和METH_KEYWORDS,其中METH_VARARGS是参数传递的标准形式,它通过Python的元组在Python解释器和C函数之间传递参数,若采用METH_KEYWORD方式,则Python解释器和C函数之间将通过Python的字典类型在两者之间进行参数传递。

4 初始化函数

所有的Python扩展模块都必须要有一个初始化函数,以便Python解释器能够对模块进行正确的初始化。Python解释器规定所有的初始化函数的函数名都必须以init开头,并加上模块的名字。对于模块mylib来说,则相应的初始化函数为:

void initmylib() 
{
  PyObject* m;
  m = Py_InitModule("mylib", mylibMethods);
}

当Python解释器需要导入该模块时,将根据该模块的名称查找相应的初始化函数,一旦找到则调用该函数进行相应的初始化工作,初始化函数则通过调用Python的C语言扩展接口所提供的函数Py_InitModule(),来向Python解释器注册该模块中所有可以用到的方法。

5 编译链接

要在Python解释器中使用C语言编写的扩展模块,必须将其编译成动态链接库的形式。下面以Linux为例,介绍如何将C编写的Python扩展模块编译成动态链接库:

$ gcc -fpic -shared -o mylib.so \
             -I/usr/include/python2.7 \
            mylib.c wrap_mylib.c

6 在Python中调用

上面编译生成的Python扩展模块的动态链接库,可以在Python中直接import。如下所示:

veelion@gtx:~$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import example
>>> example.addone(7)
8
>>>

这里生成的.so动态库和上一篇中不用Python的C语言生成的动态库是不一样的,从生成过程和使用方法就可以看出来,这里的动态库使用起来感觉就是一个Python模块,直接import就可以了。

文章来源于:猿人学网站的python教程
版权申明:若没有特殊说明,文章皆是猿人学原创,没有猿人学授权,请勿以任何形式转载。

目录
相关文章
|
14天前
|
缓存 自然语言处理 监控
阿里巴巴 item_review 接口深度分析及 Python 实现
阿里巴巴开放平台的 item_review 接口用于获取商品用户评论数据,支持评论内容、评分、买家信息等多维度分析,助力产品优化与市场策略制定。
|
9天前
|
缓存 监控 算法
item_get - Lazada 商品详情详情接口深度分析及 Python 实现
Lazada商品详情接口item_get可获取商品全维度数据,包括价格、库存、SKU、促销及卖家信息,支持东南亚六国站点,适用于竞品监控、定价策略与市场分析,助力跨境卖家精准决策。
|
13天前
|
JSON 监控 数据格式
1688 item_search_app 关键字搜索商品接口深度分析及 Python 实现
1688开放平台item_search_app接口专为移动端优化,支持关键词搜索、多维度筛选与排序,可获取商品详情及供应商信息,适用于货源采集、价格监控与竞品分析,助力采购决策。
|
14天前
|
缓存 供应链 监控
VVIC seller_search 排行榜搜索接口深度分析及 Python 实现
VVIC搜款网seller_search接口提供服装批发市场的商品及商家排行榜数据,涵盖热销榜、销量排名、类目趋势等,支持多维度筛选与数据分析,助力选品决策、竞品分析与市场预测,为服装供应链提供有力数据支撑。
|
8天前
|
供应链 监控 算法
VVICitem_get - 根据 ID 取商品详情接口深度分析及 Python 实现
VVIC(搜款网)是国内领先的服装批发电商平台,其item_get接口支持通过商品ID获取详尽的商品信息,涵盖价格、规格、库存、图片及店铺数据,助力商家高效开展市场分析、竞品监控与采购决策。
|
8天前
|
缓存 算法 数据安全/隐私保护
VVICitem_search - 根据关键词取关键词取商品列表接口深度分析及 Python 实现
VVIC item_search接口支持关键词搜索服装商品,提供价格、销量、供应商等数据,助力市场调研与采购决策。
|
9天前
|
缓存 自然语言处理 算法
item_search - Lazada 按关键字搜索商品接口深度分析及 Python 实现
Lazada的item_search接口是关键词搜索商品的核心工具,支持多语言、多站点,可获取商品价格、销量、评分等数据,适用于市场调研与竞品分析。
|
11天前
|
自然语言处理 算法 数据安全/隐私保护
item_review - Lazada 商品评论列表接口深度分析及 Python 实现
Lazada商品评论接口(item_review)可获取东南亚多国用户评分、评论内容、购买属性等数据,助力卖家分析消费者偏好、优化产品与营销策略。
|
11天前
|
缓存 监控 算法
京东item_search_best 畅销榜接口深度分析及 Python 实现
京东item_search_best接口可实时获取京东各品类畅销商品排名、销量、价格等核心数据,支持多维度榜单分析与品牌竞品监控,助力商家精准选品、制定市场策略,全面把握消费趋势。

推荐镜像

更多