使用C++编写Python扩展

简介:Python 中调用 C/C++ 程序的方法有多种,这里简单介绍使用 C/C++ 编写 Python扩展供 Python 中使用的方法。相较于使用 ctypes 加载 C/C++ 程序编译的动态库进而调用函数,扩展模块的方式,从Python 中传入参数以及从 C/C++ 程序获取返回值的过程更为规范,或者说,更能够减少程序出现错误。使用 ctypes 调用程序,在多线程 Python 程序中容易产生段错误(segfault)。

1. 扩展模块的作用

  C 扩展可以用来做两件不能直接在 Python 中做的事情: 构建新的内置对象类型、调用 C 库函数和系统调用
  为了支持扩展, Python 的 API 定义了许多函数、宏和变量,可以访问 Python 运行时系统的大部分内容。Python 的相关 API 可以通过在 C 文件中引入 “Python.h” 文件使用。
  C 扩展接口依赖于 CPython ,扩展模块无法在其他 Python 实现上工作,因此可移植性较差。

2. 用 C++ 实现 Python 扩展

2.1 引入 Python API

  如前所述,在 C++ 程序中使用 Python 的 API 需要在 C++ 程序中引入头文件 “Python.h”。而且由于 Python 可能会定义一些能在某些系统上影响标准头文件的预处理器定义,因此在包含任何标准头文件之前,必须先包含 Python.h。推荐总是在 Python.h 前定义 PY_SSIZE_T_CLEAN,实践证明,构建扩展后续是依赖这个宏定义的。因此 C++ 程序的文件头部应当如下所示:

#define PY_SSIZE_T_CLEAN
#include <Python.h>
2.2 添加 C++ 函数到扩展模块

  自己定义的模块名称为 demo ,文件名称按照习惯可以命名为 demomodule.cpp,也可以不这么做,模块名的决定性因素为下边 PyModuleDef 类型的结构体。在模块 demo 下可以调用的函数,其函数名格式为 demo_funcname,如下 demo_myFunc 为 demo 模块下 myFunc 函数的定义。一个模块可以定义多个函数。

函数的参数列表形式固定,均为(PyObject *self, PyObject *args):
  这里self与常用python类中定义函数的 self 类似,无需多看,这里的 args 则是函数接收的参数列表。
  具体接收参数的内容,需要在函数定义内部 PyArg_ParseTuple 函数中确定。此函数负责解析在 Python 中调用模块中函数时接收的参数,将其转换为对应的 C 类型数据。

函数返回值
  定义的函数可以返回对象,也可以直接返回数据。
  如果返回的是数据,则需要使用 Py_BuildValue 函数,将 C 类型的数据转换为 Python 中的数据类型。此函数的作用与上述函数 PyArg_ParseTuple 的作用相反。
  如果返回的是对象,则意味这需要在此函数中构建一个对象,之后将对象返回给 Python,这时候需要注意给对象增加引用计数,否则会导致内存泄漏的问题。
  参见这里的7-10

  添加 C++ 函数到 扩展模块的源码如下:

static PyObject *demo_myFunc(PyObject *self, PyObject *args)
{
   
   
    /* 
     * 这里是一些数据准备工作,用于接收从 Python 传递来的参数,给需要调用的 C++ 函数使用,这里的参数
     * 接收需要一些参数解析 
     */
    unsigned char *cipher_text;
    int cipher_text_length;
    unsigned char *iv_salt_file_path;
    unsigned char result[DEFAULT_RSA_KEY_LEN] = {
   
   0};
    int len;
    
    /* 
     * 对接收的参数进行解析,格式转换参见: https://docs.python.org/zh-cn/3/c-api/arg.html 
     * 这里的 s* 为接收 Python 中字符串或者 byte 类型的参数,将其解析为缓冲区中的内容, 这里的 i 
     * 为将 Python 中的整型解析为 C++ 中的整型
     */
    if (!PyArg_ParseTuple(args, "s*is*", &cipher_text
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值