⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000005.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<HTML><HEAD>  <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>发信人:&nbsp;kafa&nbsp;(staring&nbsp;at&nbsp;the&nbsp;sun),&nbsp;信区:&nbsp;Linux&nbsp;<BR>标&nbsp;&nbsp;题:&nbsp;用python扩展模块来做海龟画图&nbsp;<BR>发信站:&nbsp;BBS&nbsp;水木清华站&nbsp;(Wed&nbsp;Jan&nbsp;24&nbsp;01:26:06&nbsp;2001)&nbsp;WWW-POST&nbsp;<BR>&nbsp;<BR>
&nbsp;<BR>	我们常常希望把某个程序内部的功能通过脚本的形式暴露出来,使用户可以跟据自己的需&nbsp;<BR>要进行二次开发,例如,我们可以用Zmud的脚本语言来编机器人自动练功完成任务,Quake里&nbsp;<BR>可以用脚本描述和设计关卡,这样关卡设计就可以交给专门的人来作,减轻了程序员的工作&nbsp;<BR>量.但是,要自己开发一个成熟的脚本语言本身并不是一件简单的事,所以我们可以利用已&nbsp;<BR>有的各种脚本语言,例如Tcl/Tk,&nbsp;Perl,&nbsp;Python,&nbsp;Guile,&nbsp;Ruby等.它们都提供了把自己的&nbsp;<BR>解释器嵌入应用程序的C语言的API,我们可以直接利用它们的解释器来作语法分析等&quot;脏活&nbsp;<BR>累活&quot;,而自己只需把需要暴露的功能作成脚本语言的扩展模块.这种方法简单灵活,正变的&nbsp;<BR>越来越流行,微软也推出了script&nbsp;engine提供类似的功能.
&nbsp;<BR>
&nbsp;<BR>	python是一种解释型的,面向对象的编程语言.由于它的C&nbsp;API清楚简单,所以作为嵌入式&nbsp;<BR>的脚本语言非常合适.不知道大家有没有用过Logo?用过的人肯定记得那个海龟吧?呵呵,今&nbsp;<BR>天我们就用python来作一个简单的海龟画图程序.为了简单,我们把它做成一个python的扩&nbsp;<BR>展模块.我先解释一下,利用python的CAPI可以作两件事:扩展(extend)和嵌入(embed).扩&nbsp;<BR>展是用C编写python的模块使你在python里可以调用,简单说就是把C嵌入python;而嵌入是&nbsp;<BR>把python解释器植入到C写的应用程序里面,使程序可以解释执行python的脚本程序.扩展&nbsp;<BR>和嵌入都是在C语言和脚本语言之间作数据转换的工作,但是把python嵌入应用程序的方式&nbsp;<BR>很多,用起来非常灵活,而且往往也要涉及到扩展,所以说嵌入要比扩展复杂一些,不过原理&nbsp;<BR>是一样的.
&nbsp;<BR>
&nbsp;<BR>	好,我们先写一个没有python的简单程序,实现必需的功能.程序如下:
&nbsp;<BR>
&nbsp;<BR>/*------------------------------------------------------------------------*/
&nbsp;<BR>
&nbsp;<BR>/*&nbsp;tortoise1.c&nbsp;*/
&nbsp;<BR>
&nbsp;<BR>#include&nbsp;&lt;unistd.h&gt;
&nbsp;<BR>
&nbsp;<BR>#include&nbsp;&lt;X11/Xlib.h&gt;
&nbsp;<BR>#define&nbsp;WINDOW_SIZE&nbsp;500
&nbsp;<BR>
&nbsp;<BR>Display&nbsp;*theDisplay;
&nbsp;<BR>Window&nbsp;theWindow;
&nbsp;<BR>Screen&nbsp;*theScreen;
&nbsp;<BR>GC&nbsp;theGC;
&nbsp;<BR>double&nbsp;currentX;
&nbsp;<BR>double&nbsp;currentY;
&nbsp;<BR>double&nbsp;currentDirection;
&nbsp;<BR>int&nbsp;penDown;
&nbsp;<BR>
&nbsp;<BR>#include&nbsp;&lt;math.h&gt;
&nbsp;<BR>#define&nbsp;DEGREES_TO_RADIANS&nbsp;&nbsp;(3.1415926535897932384626433832795029L/180.0)
&nbsp;<BR>
&nbsp;<BR>/*&nbsp;复位.&nbsp;&nbsp;海龟回到窗口中心,落笔,面向北方&nbsp;*/
&nbsp;<BR>void&nbsp;tortoise_reset()&nbsp;
&nbsp;<BR>{
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;currentX&nbsp;=&nbsp;currentY&nbsp;=&nbsp;WINDOW_SIZE/2;
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;currentDirection&nbsp;=&nbsp;0.0;
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;penDown&nbsp;=&nbsp;1;
&nbsp;<BR>}
&nbsp;<BR>
&nbsp;<BR>/*&nbsp;落笔&nbsp;*/
&nbsp;<BR>void&nbsp;tortoise_pendown()
&nbsp;<BR>{
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;penDown&nbsp;=&nbsp;1;
&nbsp;<BR>}
&nbsp;<BR>
&nbsp;<BR>/*&nbsp;抬笔&nbsp;*/
&nbsp;<BR>void&nbsp;tortoise_penup()
&nbsp;<BR>{
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;penDown&nbsp;=&nbsp;0;
&nbsp;<BR>}
&nbsp;<BR>
&nbsp;<BR>/*&nbsp;转弯&nbsp;*/
&nbsp;<BR>void&nbsp;tortoise_turn(int&nbsp;degrees)
&nbsp;<BR>{
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;currentDirection&nbsp;+=&nbsp;(double)degrees;
&nbsp;<BR>}
&nbsp;<BR>
&nbsp;<BR>/*&nbsp;前进&nbsp;*/
&nbsp;<BR>void&nbsp;tortoise_move(int&nbsp;steps)
&nbsp;<BR>{
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;double&nbsp;newX,&nbsp;newY;
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;first&nbsp;work&nbsp;out&nbsp;the&nbsp;new&nbsp;endpoint&nbsp;*/
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;newX&nbsp;=&nbsp;currentX&nbsp;+&nbsp;sin(currentDirection*DEGREES_TO_RADIANS)*(double)steps;
&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;newY&nbsp;=&nbsp;currentY&nbsp;-&nbsp;cos(currentDirection*DEGREES_TO_RADIANS)*(double)steps;
&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;if&nbsp;the&nbsp;pen&nbsp;is&nbsp;down,&nbsp;draw&nbsp;a&nbsp;line&nbsp;*/
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(penDown)&nbsp;XDrawLine(theDisplay,&nbsp;theWindow,&nbsp;theGC,&nbsp;
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(int)currentX,&nbsp;(int)currentY,&nbsp;(int)newX,&nbsp;&nbsp;<BR>(int)newY);
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;in&nbsp;either&nbsp;case,&nbsp;move&nbsp;the&nbsp;tortoise&nbsp;*/
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;currentX&nbsp;=&nbsp;newX;
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;currentY&nbsp;=&nbsp;newY;
&nbsp;<BR>}
&nbsp;<BR>
&nbsp;<BR>int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;*argv[])
&nbsp;<BR>{
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;theDisplay&nbsp;=&nbsp;XOpenDisplay(NULL);
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;XSynchronize(theDisplay,&nbsp;True);
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;theScreen&nbsp;=&nbsp;DefaultScreenOfDisplay(theDisplay);
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;theWindow&nbsp;=&nbsp;XCreateSimpleWindow(theDisplay,&nbsp;RootWindowOfScreen(theScreen),&nbsp;<BR>&nbsp;
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,&nbsp;0,&nbsp;
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WINDOW_SIZE,&nbsp;WINDOW_SIZE,&nbsp;0,&nbsp;
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BlackPixelOfScreen(theScreen),&nbsp;
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WhitePixelOfScreen(theScreen));
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;theGC&nbsp;=&nbsp;XCreateGC(theDisplay,&nbsp;theWindow,&nbsp;0L,&nbsp;NULL);
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;XSetForeground(theDisplay,&nbsp;theGC,&nbsp;BlackPixelOfScreen(theScreen));
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;XMapWindow(theDisplay,theWindow);&nbsp;&nbsp;
&nbsp;<BR>
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;画个简单的正方形测试一下&nbsp;*/
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;tortoise_reset();
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;ii;
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tortoise_pendown();
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(ii=0;&nbsp;ii&lt;4;&nbsp;ii++)&nbsp;{
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tortoise_move(100);
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tortoise_turn(90.0);
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;sleep&nbsp;for&nbsp;a&nbsp;bit&nbsp;so&nbsp;the&nbsp;window&nbsp;stays&nbsp;visible&nbsp;*/
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(10);&nbsp;
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;
&nbsp;<BR>}
&nbsp;<BR>
&nbsp;<BR>/*------------------------------------------------------------------------*/
&nbsp;<BR>	
&nbsp;<BR>	你可以用&nbsp;
&nbsp;<BR>	gcc&nbsp;-o&nbsp;t1&nbsp;tortoise1.c&nbsp;-I/usr/X11R6/include&nbsp;-lX11&nbsp;-L/usr/X11R6/lib&nbsp;-lm
&nbsp;<BR>	编译它,运行一下看看.
&nbsp;<BR>	在上面这个程序里,如果要画个什么图形就要修改程序,然后重新编译调试运行,这太麻烦&nbsp;<BR>了!下面我们把它做成python的扩展模块.给python写扩展模块其实是一件很简单很模式化&nbsp;<BR>的任务,所以Python提供了一个模块框架生成器modulator,可以替你生成基本的扩展模块&nbsp;<BR>的程序框架,你只需在这个基础上面把自己的具体实现代码填上就可以了.它一般放在&nbsp;<BR>python源程序的Tools/modulator目录下面.如果你没有找到,就去下一个python的源代码&nbsp;<BR>然后编译一下就有了.
&nbsp;<BR>
&nbsp;<BR>	好,我们先运行modulator,程序的界面很简单.我们先在Module输入条里填上扩展模块的&nbsp;<BR>名字--tortoise,然后在Add&nbsp;method输入条里加入以下几个方法名:&nbsp;reset,&nbsp;pendown,&nbsp;&nbsp;<BR>penup,&nbsp;turn,&nbsp;move.&nbsp;最后按一下Generate&nbsp;code...按钮生成c代码,生成文件名最好叫做&nbsp;<BR>tortoisemodule.c以符合python扩展模块的命名习惯.退出modulator,可以看到在当前目&nbsp;<BR>录下已经多了一个叫tortoisemodule.c的文件,内容如下(中文是我加的注释):
&nbsp;<BR>
&nbsp;<BR>/*------------------------------------------------------------------------*/
&nbsp;<BR>
&nbsp;<BR>/*&nbsp;所有的python&nbsp;CAPI需要的常量,宏和函数原型都包含在这个头文件里&nbsp;*/
&nbsp;<BR>#include&nbsp;&quot;Python.h&quot;
&nbsp;<BR>
&nbsp;<BR>/*&nbsp;定义一个本模块用的例外对象&nbsp;*/
&nbsp;<BR>static&nbsp;PyObject&nbsp;*ErrorObject;
&nbsp;<BR>
&nbsp;<BR>/*&nbsp;reset函数的doc&nbsp;*/
&nbsp;<BR>static&nbsp;char&nbsp;tortoise_reset__doc__[]&nbsp;=
&nbsp;<BR>&quot;&quot;
&nbsp;<BR>;
&nbsp;<BR>
&nbsp;<BR>/*&nbsp;返回PyObject类型的指针,指向具体的python返回对象&nbsp;*/
&nbsp;<BR>static&nbsp;PyObject&nbsp;*
&nbsp;<BR>tortoise_reset(self,&nbsp;args)
&nbsp;<BR>	PyObject&nbsp;*self;	/*&nbsp;这个参数只有在做python扩展类型(extend&nbsp;type)
&nbsp;<BR>			的时候才会用到,这里我们不用&nbsp;*/
&nbsp;<BR>	PyObject&nbsp;*args;&nbsp;/*&nbsp;传入的是python的tuple类型的对象,里面包含需要的参数&nbsp;*/
&nbsp;<BR>{
&nbsp;<BR>
&nbsp;<BR>	/*&nbsp;从tuple里提取出真正的C的参数&nbsp;*/
&nbsp;<BR>	if&nbsp;(!PyArg_ParseTuple(args,&nbsp;&quot;&quot;))
&nbsp;<BR>		return&nbsp;NULL;
&nbsp;<BR>	/*&nbsp;返回Py_None类型的对象表示函数正常返回,没有错误发生&nbsp;*/
&nbsp;<BR>	Py_INCREF(Py_None);
&nbsp;<BR>	return&nbsp;Py_None;
&nbsp;<BR>}
&nbsp;<BR>
&nbsp;<BR>static&nbsp;char&nbsp;tortoise_pendown__doc__[]&nbsp;=
&nbsp;<BR>&quot;&quot;
&nbsp;<BR>;
&nbsp;<BR>
&nbsp;<BR>static&nbsp;PyObject&nbsp;*
&nbsp;<BR>tortoise_pendown(self,&nbsp;args)
&nbsp;<BR>	PyObject&nbsp;*self;	/*&nbsp;Not&nbsp;used&nbsp;*/
&nbsp;<BR>	PyObject&nbsp;*args;
&nbsp;<BR>{
&nbsp;<BR>
&nbsp;<BR>	if&nbsp;(!PyArg_ParseTuple(args,&nbsp;&quot;&quot;))
&nbsp;<BR>		return&nbsp;NULL;
&nbsp;<BR>	Py_INCREF(Py_None);
&nbsp;<BR>	return&nbsp;Py_None;
&nbsp;<BR>}
&nbsp;<BR>
&nbsp;<BR>static&nbsp;char&nbsp;tortoise_penup__doc__[]&nbsp;=
&nbsp;<BR>&quot;&quot;
&nbsp;<BR>;
&nbsp;<BR>
&nbsp;<BR>static&nbsp;PyObject&nbsp;*
&nbsp;<BR>tortoise_penup(self,&nbsp;args)
&nbsp;<BR>	PyObject&nbsp;*self;	/*&nbsp;Not&nbsp;used&nbsp;*/
&nbsp;<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -