前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python3.X使用C Extensions调用C/C++

Python3.X使用C Extensions调用C/C++

原创
作者头像
superhua
发布2019-03-07 10:40:01
1.7K0
发布2019-03-07 10:40:01
举报
文章被收录于专栏:CNN

1 创建C/C++代码文件

假设我们要在Python代码中要调用如下C语言实现的mul函数将两个整数相乘,函数add将两个整数相加,创建demo_module.c,代码如下

代码语言:txt
复制
// 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中提供了工具函数直接编译,示例代码如下。

代码语言:txt
复制
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,即输入如下命令:

代码语言:txt
复制
python setup.py build_ext --inplace

其中,--inplace表示在源码处生成pyd文件。执行上面命令后,会得到如下文件。

代码语言:txt
复制
demo.cp36-win_amd64.pyd

4 测试

测试如下:

代码语言:txt
复制
>>> import demo
>>> print(demo.mul_and_add(2,3))
12
>>> print(demo.mul_and_add(1,1))
2

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 创建C/C++代码文件
    • 1.1 函数demo_mul_and_add
      • 1.2 属性DemoMethods和demomodule
        • 1.3 PyMODINIT_FUNC
        • 2 创建setup.py
        • 3 执行编译
        • 4 测试
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档