Dev-Cpp/Mingw32 环境介绍(14)

Dev-Cpp/Mingw32 环境介绍(14)


上文回顾:

在上一文中,我们了解了如何在GCC下使用汇编语言。后来,由于个人生活环境的原因所以迟迟没有发布新的内容。当然,我这里并不想说一些不愉快的事情。不过,我没有想到居然中国还会有那么没有道德的人存在。由于,我同宿舍的一个温州人,邀请N个同学通宵看电影,影响我睡眠,造成我睡眠严重不足。更可恶的是对我进行人权侵犯!所以,就没有时间静下心来写东西了。今天刚让事情平息了一些,就想到了我的朋友你,所以马上就献上最新的文章。

第十九章 GCC下编写Python扩展

在这一章中,我向大家介绍一些有关Python语言的扩展编写的基础知识。

如果,你对Python了解了。那么你可以跳过这段,阅读后面的内容。如果不是,那么还是请您耐心了解一下Python吧。Python是一种解释性语言,而且历史悠久。他是跨平台,面向对象,使用C编写,可扩展的。他从设计一开始就是为面向对象设计的。所以,可以说,Python是一种不错的语言。有关Python的更多内容介绍,你可以看看我曾经写的另一篇Python的文章《略谈Python语言》。


Python可以使用C这一可移植的语言来进行扩展。而且,由于是用C写的。所以,扩展的速度可以和静态语言相比。所以,可以说会写Python的扩展可以大大的提高项目的运行效率。当然还有其他的好处。


不过,本文并不是介绍Python的语言的,也不是专门介绍用C扩展Python的。所以,就像我曾经所说的,我本系列的文章只是为你开启一扇扇的门。


下面我就开始我的的主题了。


在开始一切之前,请您先到 http://www.python.org 上下载最新的解释器,并安装。在我写本文的时候,最新的版本是Python 2.4.2 。这里有关Python的安装,我就不一步步的详细介绍了。


开始写程序吧!


首先,我先给出一组简单的Python代码吧。

第一个文件为add.py文件,这个文件将是会被导入的。

add.py

def add(x,y):

return(x+y)


第二个文件为main.py文件,这个文件将是会被执行的。

#main.py

import add

print add.add(256,512)


请将上面两个代码使用指定文件名(大小写也要注意,虽然在Win32下是不分大小写的)写入同一个目录下。然后,使用DOS终端在那个目录下输入 main.py 你将会看到他的输出为 768


下面我简单介绍一下两个代码的意思。

第一个文件中,定义了一个add函数,传入两个参数,分别命名为xy。函数的作用是返回x+y的数值。

第二个文件中,我们首先导入了add.py这个文件,并把他的名字空间放到add空间中。然后,我们调用add中的add函数,并传入256512。而且,最后在终端上显示add函数的返回值。


也许你会问,这不是介绍C的么?怎么又介绍Python了。其实,这个是为后面打下基础。


接着,我们试试用CPython中实现add.py的功能吧。

//add.c

#include <Python.h>


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


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;

}


z=x+y;

return Py_BuildValue("i", z);

}


static PyMethodDef addMethods[] =

{

{"add", add, METH_VARARGS, "Execute a shell command."},

{NULL, NULL, 0, NULL}

};


PyMODINIT_FUNC initadd()

{

Py_InitModule("add", addMethods);

}


这段代码也许你会觉得有些糊涂,这是什么东西?下面我为你一一介绍。

首先的#include <python.h>是必须被导入的。这个在Python的安装目录的include目录中有。其次,我们定义了一个函数叫add。由于Python中的所有东西都是对象。所以,这里在C中,为了于Python通讯,C传给Python的,Python传给C的都是PyObject这个数据类型。下面PyArg_ParseTuple这一句,是将传入的数据转换成C类型的。Py_BuildValue这个函数是将C数据类型转化成Python的数据类型,并返回他。

接着,我们要告诉Python,我们C中的Python的函数有那些。所以,addMethods这个数据组,就是为了存放这些数据的。这个就是一个列表。最后那个initadd这个函数是在Python导入模块时初始化用的。必须存在。而且,比如以 init模块名的形式在命名。其中Py_InitModule函数,是告诉PythonaddMethods这个列表所定义的内容,加入add这个名字空间中。

最后,我把代码在书写一遍。不过这次,我会用红色的部分标出套路的代码部分,也就是必须需要的地方。

#include <Python.h>


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


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;

}


z=x+y;

return Py_BuildValue("i", z);

}


static PyMethodDef addMethods[] =

{

{"add", add, METH_VARARGS, "Execute a shell command."},

{NULL, NULL, 0, NULL}

};


PyMODINIT_FUNC initadd()

{

Py_InitModule("add", addMethods);

}


最后,我们来把这个代码编译一下吧。你也许会问,既然是跨平台的,是否对于不同的操作系统,要使用不同的编译方式。答案是否定的。Python自带的编译脚本可以为你完成一切的编译过程。不过,你要在开始要把你的MinGW设置进环境变量中。具体可以看本系列文章第一章到第三章。

下面给出Python编译安装脚本的文件。

#!/usr/bin/python

#setup.py


from distutils.core import setup, Extension


module1 = Extension(name='add, sources = ['add.c'])


setup (name = 'PackageName', version = '1.0', description = 'This is a demo package', ext_modules = [module1])

这段代码是告诉Python如何来组成你的包。首先,第一句#!/usr/bin/python 是在BSD/Linux/Unix下告诉系统使用什么解释器运行代码在Win32下有和没有没什么区别。

Module1=Extension('mytest',sources=['add.c']是定义你第一个要编译扩展的信息。后面的setup函数,就是用来定义包的,其中在ext_modules中就在列表中加入了我们刚才定义的模块信息。这样,Python会更具你给的信息,更具不同的平台,操作系统自动的编译出合适的扩展文件。


dos终端下输入setup.py build -cmingw32 如果没有错误,那么在编译后,你会在build目录中的子目录中找到add.pyd这个文件,这个就是PythonC扩展文件。把第一个例子中的add.py从目录中移除,并删除add.pyc这个文件(这个文件会在Python导入时自动生成,方便下次导入时快速执行和导入)。再将刚才编译的add.pyd放到该目录下。像刚才一样的运行,你看到了什么?和刚才一样的运行结果。对的。我这里的C扩展就是实现了刚才Python所定义的功能。怎么样是不是觉得还有很多不明白?如果你要深入Python的扩展编程,你可以看看Python的参考手册 Python/C API 这部分内容。下面列出一些Extension中一些参数的意义。


include_dirs 定义头文件的目录地址,默认情况下Python头文件目录的地址已经被定义了。

library_dirs 定义了库文件的目录地址,默认情况下Python的库文件目录也被包含了。

Libraries 定义在编译时要使用的库文件名,这个有点像GCC中在-l后面加的参数。


当然,还有其他很多参数。这里只是列出了常用的几个基本参数名和意义。希望我为你开启的门够宽敞。如果有兴趣,可以查看Python的参考手册。相信对你一定有很大的帮助。

好了,最后祝你在学习的过程中一切顺利,Good Luck。并且,希望有什么问题请你尽量提出来。


文外音:

就像我开始所说的,我由于生活环境的因素造成我迟迟没有写新的文章。这一点,是让我刚到非常亏欠于你的。不过,这也是最近一个月没有出文章的原因。前一阶段我也说过了,没有创意了。后来,偶然之间找到了中级篇的指导方向,所以马上就有了新文章的构思。希望我这篇文章能够让你们满意。谢谢你长久以来对我的支持。因为有了你,我才会有不懈的动力写下去。谢谢。如果你有任何的问题请到 http://blog.csdn.net/visioncat/ 上提出你的问题和建议。


STUDIO软件开发组(SDT)
STUDIO Development Team
北斗星君(黄庠魁)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值