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函数,传入两个参数,分别命名为x和y。函数的作用是返回x+y的数值。
  第二个文件中,我们首先导入了add.py这个文件,并把他的名字空间放到add空间中。然后,我们调用add中的add函数,并传入256和512。而且,最后在终端上显示add函数的返回值。
  也许你会问,这不是介绍C的么?怎么又介绍Python了。其实,这个是为后面打下基础。
  接着,我们试试用C在Python中实现add.py的功能吧。
  //add.c
  #include
  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的安装目录的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函数,是告诉Python将addMethods这个列表所定义的内容,加入add这个名字空间中。
  最后,我把代码在书写一遍。不过这次,我会用红色的部分标出套路的代码部分,也就是必须需要的地方。
  #include
  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这个文件,这个就是Python的C扩展文件。把第一个例子中的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
  北斗星君(黄庠魁)

本文转自
http://blog.csdn.net/visioncat/archive/2005/11/16/531152.aspx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值