c调用python第三方包_【Python笔记】如何用C语言实现Python第三方扩展包

Python支持C/C++实现的第3方扩展包,在性能要求高的场合,这种特性显得尤其重要。

本文以实例说明定制Python扩展包的基本步骤。

1. 扩展包源码实现

按照Python官网教程Extending Python with C or C++说明的步骤,扩展模块的源文件实现如下:

#include

// forward declaration

void initpyext(void);

// self-defined error obj

static PyObject * ExtError;

int main(int argc, char * argv[])

{

// Pass argv[0] to the Python interpreter

Py_SetProgramName(argv[0]);

// Initialize the Python interpreter. Required.

Py_Initialize();

initpyext();

Py_Exit(0);

// not reached, warning will be printed when build the extension

}

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

{

const char * command;

int sts;

if(!PyArg_ParseTuple(args, "s", &command)) {

return NULL;

}

sts = system(command);

if(sts < 0) {

PyErr_SetString(ExtError, "System command failed");

return NULL;

}

return PyLong_FromLong(sts);

}

static PyMethodDef PyextMethods[] = {

{"ext_cmd", py_ext_test_func, METH_VARARGS, "Execute a shell command." },

{NULL, NULL, 0, NULL}

};

PyMODINIT_FUNC initpyext(void)

{

PyObject * m;

m = Py_InitModule("pyext", PyextMethods);

if(NULL == m) {

return;

}

ExtError = PyErr_NewException("pyext.error", NULL, NULL);

Py_INCREF(ExtError);

PyModule_AddObject(m, "error", ExtError);

}上面的代码展示的是一个典型的针对Python的c扩展源码布局:

1. 定义main函数,作为扩展模块的入口

2. main函数调用initpyext(),initpyext函数名必须是initname格式,其中name是扩展模块名(扩展模块名由Py_InitModule的参数指定)

3. initpyext函数中,调用Py_InitModule初始化扩展模块名及其支持的方法名,其中method list是由static数组PyextMethods定义的

4. PyextMethods数组中,注册扩展模块支持的methods的name及其对应的函数指针

5. 为每个在PyextMethods数组中注册的method定义并实现具体的行为

2. 扩展文件编译/链接

$> python setup.py build

running build

running build_ext

building 'pyext' extension

gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/slvher/tools/python-2.7.5/include/python2.7 -c pyext.c -o build/temp.linux-x86_64-2.7/pyext.o

pyext.c: In function `main':

pyext.c:28: warning: control reaches end of non-void function

gcc -pthread -shared build/temp.linux-x86_64-2.7/pyext.o -o build/lib.linux-x86_64-2.7/pyext.so注意:这里直接用python调用setup.py是因为在PATH中设置了python的默认环境变量,如果当前系统默认的python解释器不是我们想要用来编译扩展的解释器时,需要用python的绝对路径调用。

3. 安装扩展包

$> python setup.py install

running install

running build

running build_ext

running install_lib

copying build/lib.linux-x86_64-2.7/pyext.so -> /home/slvher/tools/python-2.7.5/lib/python2.7/site-packages

running install_egg_info

Writing /home/slvher/tools/python-2.7.5/lib/python2.7/site-packages/TestPyExtPackage-1.0-py2.7.egg-info4. 验证是否可用

安装成功后,进入python解释器,import扩展模块后,可以调用其方法名:

>>> import pyext

>>> pyext.ext_cmd("echo hello world")

hello world

0L

>>>

====================== EOF ==================

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值