编写python的C语言扩展
最近一直在学python,的确为python的简洁所折服,因为工作中可能会经常用到python和c打交道的情况,所以研究了一下C语言扩展的写法,可能比较基础,让高手们见笑啦。
发现原来在windows和linux下面,对C扩展的编译方法是不一样的,我们先来看windows版的。
注:文章部分内容引用来自:
http://www.chinaunix.net/jh/55/563784.html
我们用C实现一个简单的加法。
首先新建一个文件add.c,代码如下:
#include <Python.h>;
static PyObject* add(PyObject *self, PyObject *args);
//一定声明为static,把他们限制在这个文件范围里。 几乎所有的参数都是PyObject类型。 在python,每个东西都是object。
static PyObject* add(PyObject* self, PyObject* args)
{
int x=0 ;
int y=0;
int z=0;
if (! PyArg_ParseTuple(args, "i|i", &x, &y))
return NULL;
/*第一个参数是self,这个是python用的, 每个函数都要有。我们暂时不管。args是一个参数列表。她把所有的参数都整合成一个string。所以
我们需要从这个string里来解析我们的参数。PyArg_ParseTuple来完成这个任务。第一个参数是args, 就是我们要转换的参数。第二个是格式符号。
“s”代表是个string。 从args里提取一个参数就写"s", 两个的话就写"s|s", 如果是一个string,一个int,就写"s|i", 和printf差不多。第三个
参数就是提取出来的参数放置的真正位置。必须传递这个参数的地址。对于add, 他将提取两个参数。分别是x和y。*/
z=x+y;
return Py_BuildValue("i", z);
/*调用完之后我们需要返回结果。这个结果是c的type或者是我们自己定义的类型。必须把他转换成PyObject, 让python认识。这个用Py_BuildValue
来完成。他是PyArg_ParseTuple的逆过程。他的第一个参数和PyArg_ParseTuple的第二个参数一样, 是个格式化符号。第三个参数
是我们需要转换的参数。Py_BuildValue会把所有的返回只组装成一个tutple给python。*/
}
static PyMethodDef addMethods[] =
{
{"add", add, METH_VARARGS, "Execute a shell command."},
{NULL, NULL, 0, NULL}
};
/*这个是一个c的结构。他来完成一个映射。 我们需要把我们扩展的函数都映射到这个表里。表的第一个字段是python真正认识的。是python
里的方法名字。 第二个字段是python里的这个方法名字的具体实现的函数名。 在python里调用add, 真正执行的是用c写的add函数。
第三个字段是METH_VARARGS, 他告诉python,add是调用c函数来实现的。第四个字段是这个函数的说明。如果你在python里来help这个函数,
将显示这个说明。相当于在python里的函数的文档说明。*/
PyMODINIT_FUNC initadd()
{
Py_InitModule("add", addMethods);
}
/*注意,这个函数的名字不能改动。 必须是init+模块名字。 我们的模块名字是add。所以这个函数是initadd()。
这样python在导入add 的模块时候,才会找到这个函数,并调用。这个函数调用Py_InitModule来将模块名字和映射表结合在一起。
他表示,add这个模块使用addMethods这个映射表。python应该这样导入我们的module的.*/
新建一个setup.py,内容如下:
from distutils.core import setup, Extension
module1 = Extension('add', sources = ['add.c'])
setup (name = 'PackageName', version = '1.0', description = 'This is a demo package', ext_modules = [module1])
组建:(由于我的机器上装了mingw,所以指定了mingw32。默认的编译器是vs2008。参考:http://docs.python.org/install/index.html#gnu-c-cygwin-mingw)
python setup.py build --compiler=mingw32
执行后会在当前目录生成一个build目录及文件:
build\lib.win32-2.6\add.pyd
将add.pyd拷贝到当前目录,并写一个测试文件test.py,代码如下:
import add
print add.add(3,4)
执行一下,输出为7
OK,基本上就是如此了。
----------------------------我是华丽的分割线--------------------------
在linux下的话,会有少许不同.
即直接用makefile将add.c编译成.so,python可以直接import,makefile代码如下:
PYLIB = /usr/bin
PYINC = /usr/include/python2.6
all: add.c
gcc add.c -g -I$(PYINC) -shared -L$(PYLIB) -lpython2.6 -o add.so
clean:
rm -f add.so
用同样的测试代码,可以测试通过。
----------------------------我是华丽的分割线--------------------------
代码下载
建议继续学习:
- 配置Nginx+uwsgi更方便地部署python应用 (阅读:105476)
- 如何成为Python高手 (阅读:53493)
- python实现自动登录discuz论坛 (阅读:31655)
- python编程细节──遍历dict的两种方法比较 (阅读:19065)
- 每个程序员都应该学习使用Python或Ruby (阅读:16334)
- 使用python爬虫抓站的一些技巧总结:进阶篇 (阅读:12190)
- 30分钟3300%性能提升――python+memcached网页优化小记 (阅读:12224)
- 我的PHP,Python和Ruby之路 (阅读:11912)
- Python处理MP3的歌词和图片 (阅读:8391)
- 关于使用python开发web应用的几个库总结 (阅读:7508)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:Dante 来源: Vimer
- 标签: python 扩展
- 发布时间:2010-05-12 13:21:53
- [69] Twitter/微博客的学习摘要
- [67] IOS安全–浅谈关于IOS加固的几种方法
- [65] android 开发入门
- [65] 如何拿下简短的域名
- [63] find命令的一点注意事项
- [62] Go Reflect 性能
- [61] 流程管理与用户研究
- [60] Oracle MTS模式下 进程地址与会话信
- [59] 图书馆的世界纪录
- [57] 读书笔记-壹百度:百度十年千倍的29条法则