打印

支持插件的程序设计

支持插件的程序设计

作者:dorainm

看到很多软件,尤其老外的,大型软件,异常支持插件功能
主程序简洁了不说,灵活性,
而且貌似老外闲人很多,帮忙编写支持其它功能的新插件
逐渐,该软件的功能就变得完善异常


插件有2种存在方式:

1、脚本
     一个插件,就是一段脚本,主程序读取某个脚本,需要解释它,
       然后再有选择性、逻辑性地执行早已编译主程序内的相对应的二进制代码!
     脚本不许要系统的任何支持(系统:哼,我不给你 I/O 操作),也跟系统环境没有关系
     编写这种脚本只需要一个文本编辑器,例如 vim 或 emacs 就可以了
     但执行效率会稍稍逊色,而且脚本的设计代码容易暴露
     针对陌生的脚本插件,如果主程序拥有足够的容错能力,还是能够避免程序崩溃
     (dorainm:设计个逻辑无限循环的恶意插件,让主程序瞎耗去吧)

2、二进制
     这种脚本,是一种链接库,由各种函数的已经编译好的二进制字符组成
     而且必须要求操作系统能够支持一个程序调用链接库的功能
     (类似win32的dll动态链接库,*nix的.o/.so共享对象)
     还需要针对不同操作系统,软、硬件环境编译出相应的二进制代码,
     当然,编写插件的时候,需要额外的编译器,如 gcc
     这种插件执行效率相对比较高,源码相对也比较不透明
     因为它本身就是已经被编译了的可执行二进制代码
     但是一旦遇到恶意或者劣质的插件,主程序就会崩溃!


下面我们来介绍第二种插件的实现思想与方法,
一则,学会了第二种,第一种方法无非是编译器的工作变成了主程序的任务
二来,我们可以学习动态链接库的程序写法
     它即能减少程序的大小,也能提高程序编译过程中的时间花费,
     更能提高程序灵活性,比如升级、补丁;
     不可能我们的软件只有一个可执行的二进制文件,
     (比如CS,就一个 1.3G 大的 .exe,
     升级方面不说,如果作者觉得 AWP 的甩枪需要修正,
     修改源码,让电脑编译,我 阿富汗 旅游!!
     旅游回来,汗,修改源码的时候,不小心多加了个逗号,
     重新修正,再编译,得,这回去 伊拉克 旅游...)

关于插件的思想,是dorainm自己想的
不知道与当前各大软件的设计是否相似,如果有冗余或错误的地方,
还望斧正

环境:
系统 linux 2.6.15
编译器 gcc 4.1.0
文本编辑 emacs 21.4.1

关于动态链接库的介绍,引用 雨亦奇 的 <LINUX系统中动态链接库的创建与使用>
[quote]
大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library)。这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一部分,而是根据执行程
附件: 您所在的用户组无法下载或查看附件
mail: dorainm@gmail.com
blog: dorainm.cublog.cn

TOP

乘法、除法插件的源码,想必就不需要提供来,也是修改一个字符!
下面看它们实现的效果
引用:
[dorainm@localhost plug_simple]$ ls
d_add.c   d_div.c  d_plug.h  d_sub.so  simple
d_add.so  d_mul.c  d_sub.c   main.c
[dorainm@localhost plug_simple]$ cc --shared -o d_mul.so d_mul.c
[dorainm@localhost plug_simple]$ cc --shared -o d_div.so d_div.c
[dorainm@localhost plug_simple]$ ls
d_add.c   d_div.c   d_mul.c   d_plug.h  d_sub.so  simple
d_add.so  d_div.so  d_mul.so  d_sub.c   main.c
[dorainm@localhost plug_simple]$ ./simple ./d_mul.so
a plug-in simple, by dorainm, dorainm@gmail.com
use shared object file : [ ./d_mul.so ]
load plug [ ./d_mul.so ] successfully.
the result to 5, 3 : 15.
[dorainm@localhost plug_simple]$ ./simple ./d_div.so
a plug-in simple, by dorainm, dorainm@gmail.com
use shared object file : [ ./d_div.so ]
load plug [ ./d_div.so ] successfully.
the result to 5, 3 : 1.
[dorainm@localhost plug_simple]$
乘法、除法插件也实现来!

当然,我们还可以编写,
比如把 x当作成绩,y当作及格标准,res返回该学生成绩是否合格的判断成绩的插件

这样,一个主程序,不修改自己任何代码,就可以实现了各种各样的功能:)


真实的软件

各种插件可能由一些插件列表维护,
比如一个插件配置的文本文件 plug.conf,里面有插件对应的位置列表
或者把插件都放置在某个文件夹中,
比如plug-in文件夹里,就丢着为主程序提供各种功能的.so插件

主程序运行起来时,需要建立一张插件的表,存储插件列表
再读取相应的信息,给用户显示:
看,当前有这些这些插件
当用户选择其一,进行操作时,软件就调入该动态链接库
圆满完成用户预先想要的功能

这就是插件的奥秘!
mail: dorainm@gmail.com
blog: dorainm.cublog.cn

TOP

呵呵。。。我一直用glib的gmodule。。。
也不知道有什么优势。。。就是喜欢glib/gtk。。。

不过插件这篇文章介绍的插件实现方法只限于C语言。。。
至于C++的实现方法要动一点脑筋哟。。。

等我回学校再发一个C++的实现方法。。。
Mike

TOP