python 调用c_Python调用C

1. 引言

众所周知,Python语言简单、易学、开源、具有丰富的库,Python的第一个编译器是用C语言实现的。但Python的缺点也非常明显,最让人诟病的就是Python的性能问题。因此,为了提高程序的运行效率,通常会将程序的关键部分使用C或C++重写,编译成动态链接库,然后在Python(CPython)中进行调用。运行环境:Ubuntu 16.04、Python 2.7、Python 3.5。

2. Python C扩展

2.1 普通C函数

void hello()

{

printf("Hello World!\n");

}

int add(int a, int b)

{

return a + b;

}

2.2 Python C扩展

Python扩展模块由以下几部分组成:

头文件

调用的C函数

模块方法表

模块初始化函数

具体实现demo.c如下:

// 包含Python头文件

#include

// 兼容Python3

#if PY_MAJOR_VERSION >= 3

#define PYTHON3

#endif

// hello函数实现

static PyObject* hello(PyObject *self, PyObject *args)

{

printf("Hello World\n");

return Py_None;

}

// add函数实现

static PyObject* add(PyObject *self, PyObject *args)

{

int a, b;

if(!PyArg_ParseTuple(args, "ii", &a, &b))

{

return NULL;

}

return Py_BuildValue("i", a + b);

}

// 模块方法表

static PyMethodDef TwoMethods[] = {

{ "hello", hello, METH_NOARGS, "Print Hello" },

{ "add", add, METH_VARARGS, "Add two integers"},

{ NULL, NULL, 0, NULL }

};

#ifdef PYTHON3

// Python3模块定义结构体

static struct PyModuleDef testModule = {

PyModuleDef_HEAD_INIT,

"testModule",

"Test Module",

-1,

TwoMethods

};

// Python3模块初始化函数

PyMODINIT_FUNC PyInit_demo(void)

{

return PyModule_Create(&testModule);

}

#else

// Python2模块初始化函数

PyMODINIT_FUNC initdemo(void)

{

Py_InitModule("demo", TwoMethods);

}

#endif

2.3 编译并测试

编写setup.py文件:

from distutils.core import setup, Extension

demo = Extension('demo', sources = ['demo.c'])

setup(name = 'C extension module', version = '1.0', description = 'This is a demo', ext_modules = [demo])

生成动态链接库的命令如下:

#python2

$ python setup.py build_ext --inplace

running build_ext

building 'demo' extension

x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -I/usr/include/python2.7 -c demo.c -o build/temp.linux-x86_64-2.7/demo.o

x86_64-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -Wdate-time -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wl,-Bsymbolic-functions -Wl,-z,relro -Wdate-time -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security build/temp.linux-x86_64-2.7/demo.o -o /workspace/python-c/demo.so

#python3

$ python3 setup.py build_ext --inplace

running build_ext

building 'demo' extension

x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.5m -c demo.c -o build/temp.linux-x86_64-3.5/demo.o

x86_64-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-x86_64-3.5/demo.o -o /workspace/python-c/demo.cpython-35m-x86_64-linux-gnu.so

hello,add函数测试:

>>> from demo import hello, add

>>> hello()

Hello World

>>> add(2, 3)

5

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值