Python3.X使用C Extensions调用C/C++
Posted 走召大爷
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python3.X使用C Extensions调用C/C++相关的知识,希望对你有一定的参考价值。
1 创建C/C++代码文件
假设我们要在Python代码中要调用如下C语言实现的mul
函数将两个整数相乘,函数add
将两个整数相加,创建demo_module.c
,代码如下
// pulls in the Python API
#include <Python.h>
static int mul(int a,int b)
return a*b;
static int add(int a,int b)
return a+b;
// C function always has two arguments, conventionally named self and args
// The args argument will be a pointer to a Python tuple object containing the arguments.
// Each item of the tuple corresponds to an argument in the call's argument list.
static PyObject* demo_mul_and_add(PyObject *self, PyObject *args)
const int a, b;
// convert PyObject to C values
if (!PyArg_ParseTuple(args, "ii", &a, &b))
return NULL;
int c=mul(a,b);
int d=add(c,c);
// convert C value to PyObject
return Py_BuildValue("i", d);
// module's method table
static PyMethodDef DemoMethods[] =
"mul_and_add", demo_mul_and_add, METH_VARARGS, "Mul and Add two integers",
NULL, NULL, 0, NULL
;
static struct PyModuleDef demomodule =
PyModuleDef_HEAD_INIT,
"demo", /* module name */
NULL, /* module documentation, may be NULL */
-1,
DemoMethods /* the methods array */
;
PyMODINIT_FUNC PyInit_demo(void)
return PyModule_Create(&demomodule);
1.1 函数demo_mul_and_add
其中,函数demo_mul_and_add
是C语言与Python语言的桥梁函数。demo_mul_and_add
函数内使用PyArg_ParseTuple
函数将Python类型的参数转为C语言中的数据类型。其中参数ii
表示连续两个Python中的int数据转为C语言中的int。常用的数据类型转换如下。
字符 | C语言类型 | Python |
---|---|---|
c | char | 长度为1的字符串转为C语言的字符 |
s | char array | Python中字符串转为C语言字符数组 |
d | double | Python float转为C语言中double |
f | float | Python中float转为C语言中float |
i | int | Python中int转为C语言中int |
l | long | Python中int转为C语言中long |
o | PyObject* | Python中的类对象转为C语言中PyObject |
与函数PyArg_ParseTuple
相反,函数Py_BuildValue
将C语言中的数据类型转为Python对象,类型映射关系是一致的,看几个简单例子如下。
示例代码 | 转为Python对象 |
---|---|
Py_BuildValue(“s”, “AB”) | “AB” |
Py_BuildValue(“i”, 1000) | 1000 |
Py_BuildValue("(iii)", 1, 2, 3) | (1, 2, 3) |
Py_BuildValue("si,si", "a’, 4, “b”, 9) | “a”: 4, “b”: 9 |
Py_BuildValue("") | None |
1.2 属性DemoMethods和demomodule
定义的PyMethodDef
类型属性DemoMethods用于登记转换的函数列表,即本例的demo_mul_and_add
函数,其中"mul_and_add"
用于指定Python代码中调用该函数时对应的函数名称。
定义的PyModuleDef
类型属性demomodule 用于Module名称及其中的函数列表。
1.3 PyMODINIT_FUNC
PyMODINIT_FUNC 用于指定初试化入口函数,其中PyModule_Create用于创建模块
2 创建setup.py
写好了Module中的C代码后,接下来要将其编译为pyd文件(pyd文件能直接被Python代码import)。Python中提供了工具函数直接编译,示例代码如下。
from distutils.core import setup, Extension
module1 = Extension('demo',
sources = ['demo_module.c']
)
setup (name = 'a demo extension module',
version = '1.0',
description = 'This is a demo package',
ext_modules = [module1])
3 执行编译
调用setup.py
,即输入如下命令:
python setup.py build_ext --inplace
其中,–inplace表示在源码处生成pyd文件。执行上面命令后,会得到如下文件。
demo.cp36-win_amd64.pyd
4 测试
测试如下:
>>> import demo
>>> print(demo.mul_and_add(2,3))
12
>>> print(demo.mul_and_add(1,1))
2
以上是关于Python3.X使用C Extensions调用C/C++的主要内容,如果未能解决你的问题,请参考以下文章