Linu下插件开发应用案例_第1页
Linu下插件开发应用案例_第2页
Linu下插件开发应用案例_第3页
Linu下插件开发应用案例_第4页
Linu下插件开发应用案例_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Linux下插件开发应用案例方汉在Linux上愈来愈多的应用程序利用Plugin编程技术来实现扩展功能,目前应用比较广泛的有GimpNetscape/Mozilla、XMMS和Nessus等,本文将简单介绍这些软件的Plugin的架构和编程。给软件以生命力的Plugin众所周知,要让一个软件具有生命力,最重要的一点是要让它提供并支持越来越多的功能,而这一点单凭开发者自身是很难独立做到的,需要让第三方的软件开发者可以通过作者提供的一种途径来为该软件添加功能。最初,人们是使用关联模式,也就是像Windows下的文件扩展名一样,根据不同的文件关联,使用不同的软件打开相应的文件。这种方式编写扩展最为容易和自由,但是存在一定的缺陷,首先是不能利用宿主软件的资源,其次是软件的界面风格不易统一、灵活性不好。后来出现了Plugin结构,也就是利用动态连接库的方式制作Plugin(在Windows平台下是DLL、在Linux/Unix环境下是shareobjectlibrary),Plugin程序只能依附于宿主程序运行,不能独立运行,使用Plugin的优点是系统开销小、速度快,同宿主程序结合紧密、灵活性好。在Linux上,最著名的Plugin架构就是Netscape提出的Plugin架构,比较出名的还有WinAmp()(在Linux上改名叫XMMS,网址为),这个MP3播放软件中多彩多姿的插件(Plugin)系统和皮肤(skin)系统为其一统天下做出了不可磨灭的贡献。现在WinAmp已开始提供一个NSDN(NullSoftDevelopNetwork)来让大家开发Plugin,由此可见Plugin对于一个软件来说是多么重要。Linux下插件安装在Linux上,使用某种软件的Plugin的方法很简单,一般该宿主软件都会提供一些缺省的Plugin,而且会搜寻相应的Plugin目录,用户可以把Plugin安装到系统的Plugin目录下也可以安装到自己的目录下。比如,要安装Netscape的Plugin,可以设定$NPX_PLUGIN_PATH这个环境变量到你的新Plugin目录,或者把Plugin安装到下列路径上:/usr/local/lib/netscape/Plugins$MOZILLA_HOME/Plugins$HOME/.netscape/PluginsNetscape会自动搜寻这些Plugin目录来自动加载相应的Plugin,其他的软件如Gimp、XMMS和Nessus等的使用方法与此大同小异。最简单Plugin架构的实现首先,我们要编写一个宿主程序,该宿主程序必须为Plugin提供相应的接口,例如在本例子中的Action,然后宿主程序可以通过dlopen来打开相应的Plugin,调用dlsym和createproc来创建Plugin的进程,最后还要调用Plugin执行相应的动作,一切完成后要用dlclose来关闭Plugin。宿主程序的源代码如下:Plugin_main,h#ifndef_PLUG_MAIN_H_#define_PLUG_MAIN_H_//定义强制C类型以回避C++命名规范,这样我们就可以定义dlsym()#ifdef__cplusplusextern""C""{#endifclassCPlugMain{public:virtualintAction()=0;};//下面是Plugin的通用函数,每个Plugin都会重载这个函数,主程序将创建惟一的子进程externCPlugMain囹CreatePlug();typedefCPlugMain囹(囹CREATEPLUG_PROC)();#ifdef__cplusplus#endif//#definecplusplus#endif//#define_PLUG_MAIN_H_Plugin_main,cpp#include""Plugin_main.h""#includeVstdio.h>#includeVdlfcn.h>〃动态链接库相关函数//下面将定义固定的Plugin名称,读者可以自行定义如同Windows注册表那样的Plugin注册系统#defineNUM_PLUGINS2char0szPlugins[]={""./Plugin1.so"",""./Plugin2.so""};intmain(intargc,char00argv){CREATEPLUG_PROCcreateproc[NUM_PLUGINS];CPlugMain0pPlugins*NUM_PLUGINS+;void0handle*NUM_PLUGINS+;char0error;inti;//加载所有Pluginfor(i=0;iVNUM_PLUGINS;i++){printf(""加载Plugin%s."",szPlugins[i]);//加载Plugin动态链接库if(NULL==(handle[i]=dlopen(szPlugins[i],RTLD_LAZY))){handle[i]=NULL;printf(""dlopenerror(%s)"",szPlugins[i]);}else{//取得CreatePlug的地址createproc[i]=(CREATEPLUG_PROC)dlsym(handle[i],""CreatePlug"");if((error=dlerror())!=NULL){dlclose(handle[i]);handle[i]=NULL;printf(""dlsymerror(%s)"",szPlugins[i]);}else{//创建Plugin进程pPlugins[i]=createproc[i]();}}}//执行Plugin的动作printf(""正在运行Plugin.."");for(i=0;iVNUM_PLUGINS;i++){if(handle[i]!=NULL){pPlugins[i]->Action();}}//关闭Pluginfor(i=0;iVNUM_PLUGINS;i++){if(handle[i]!=NULL){dlclose(handle[i]);handle[i]=NULL;return0;下面是一个最简单的Plugin,只包含了Plugin_main.h这个头文件,并且实现Action和CreatePlug这两个函数。源程序如下:Plugin_1.hifndef_PLUGIN_1_H_#define_PLUGIN_1_H_include“Plugin_main.h〃classCPlugin10publicCPlugMain0public0virtualintAction0000#endif//#define_PLUGIN_1_HPlugin_1.cppinclude'Plugin_main.hinclude“Plugin1.h"includeVstdio.h>printf(""这是Plugin1,运行正常"");return0;}CPIugMain囹CreatePlug(){returnnewCPIugin1;}}值得注意的是,编译这个Plugin的时候要使用-shared参数来产生动态链接库.so文件,例如:gcc-oPIugin1.soPIugin1.o-shared。Plugin开发实战我们来看看如何为现有的一些软件编写Plugin,其中最复杂的是Netscape4.x和Mozilla(Netscape6.x)的Plugin编写工作,而Xmms/Gimp/Nessus的Plugin相对来说要容易编写得多。1.Netscape4.x/Mozilla的Plugin结构Netscape的Plugin结构相对比较古老,Netscape提供的接口包括NPP系列和NPN系列,其中NPP系列中Plugin必须自行实现,包括:NPP_Destroy、NPP_DestroyStream、NPP_GetJavaClass、NPP_HandleEvent、NPP_Initialize、NPP_New、NPP_NewStream、NPP_Print、NPP_SetWindow、NPP_Shutdown、NPP_StreamAsFile、NPP_URLNotify、NPP_Write和NPP_WriteReady。NPN系列是Plugin要求Netscape提供的一些函数,包括:NPN_DestroyStream、NPN_GetJavaEnv、NPN_GetJavaPeer、NPN_GetURL、NPN_MemAlloc、NPN_MemFlush、NPN_MemFree、NPN_NewStream、NPN_PostURL、NPN_RequestRead、NPN_Status、NPN_UserAgent、NPN_Version和NPN_Write。每种Plugin都有两种工作模式,即嵌入式和全页面方式,Plugin需要实现的工作包括以下内容:登记一种或几种Plugin要操作的MIME格式;在浏览器的窗口中间绘图;(3)接收鼠标/键盘输入;(4)从相应的URL中下载/发送数据。用户如果要开发Netscape的Plugin,首先要在/pub/sdk/Plugin/unix下载相应的SDK文件,里面有简单的例子,用户可以自行修改成自己的Plugin。Mozilla/Netscape6.x的Plugin架构是目前最先进的一种,它主要有下列优点:提供基于C++的API函数;提供了XPCOM,它是COM(theComponentObjectModel)的一个子集,XP的意思是cross-platform(跨平台),这使得新的Plugin的跨平台性和不同版本的兼容性得到了极大的提高;完全向后兼容,所有老的4.x系列的NetscapePlugin都可以继续使用。Mozilla的Plugin架构将原来的NPP系列接口改变为:NPIPIugin、NPIPluginInstance和NPIPIuginStream三个类;NPN系列接口被扩充为NPIPluginManager、NPIPluginManagerStream、NPIPluginInstancePeer和NPIPluginStreamPeer四个类,其中NP的意思是NetscapePlugin, I的意思是Interface。linux插件开发参考文献xmms插件开发指南:gimp插件开发指南:/plugin_devel.htmlnessus插件开发指南:/doc/plugins_api.txt/doc/nasl.htmlnetscape4.x系列插件开发指南:/docs/manuals/communicator/plugin/index.htm/pub/sdk/plugin/unixmozilla囹netscape6.x系列插件开发指南:/development/extmoz.html/docs/plugin.html/docs/extendmoz.html要开发Mozilla的Plugin,用户需要下载Mozilla的源代码,而Plugin的例子程序可以在/mozilla/source/Plugin/上查阅,具体文档请参阅附录。2.Xmms的Plugin架构Xmms的Plugin分为输入(Input)、输出(Output)、可视化(Visualization)、通用(General)、效果(Effect)和其他(Misc)五种,要开发Xmms的Plugin需要安装xmms-devel这个软件包,下面是一个最简单的Xmms可视化的Plugin:xmms-Plugin.c#includeVgtk/gtk.h>#include""xmms/Plugin.h""staticGtkWidget囹window=NULL,囹button;staticvoidPlugin_init(void);staticvoidPlugin_cleanup(void);VisPluginPlugin_vp={NULL,NULL,0,NULL,個描述函数0/0,1,Plugin_init,/0初始化函数0/Plugin_cleanup,/0结束函数0/NULL,/0关于函数0/NULL,/0配置函数0/NULL,/0disable_Plugin0/NULL,/0playback_start0/NULL,/0playback_stop0/NULL,/0render_pcm0/NULL/0render_freq0/};VisPlugin0get_vPlugin_info(void){Plugin_vp.description=g_strdup_printf(""HelloWorld!"");return&&Plugin_vp;}#defineWIDTH250#defineHEIGHT100staticvoidPlugin_destroy_cb(GtkWidget囹w,gpointerdata){Plugin_vp.disable_Plugin(&&Plugin_vp);}staticvoidPlugin_init(void){if(window)return;window=gtk_window_new(GTK_WINDOW_DIALOG);gtk_window_set_title(GTK_WINDOW(window),""HelloWorld"");gtk_window_set_policy(GTK_WINDOW(window),FALSE,FALSE,FALSE);gtk_widget_realize(window);gtk_widget_set_usize(window,WIDTH,HEIGHT);button=gtk_button_new_with_label(""HelloWorld"");gtk_container_add(GTK_CONTAINER(window),button);gtk_widget_show(button);gtk_widget_show(window);}staticvoidPlugin_cleanup(void)if(window)gtk_widget_destroyHwindow囹}}3.Gimp的Plugin架构Gimp的Plugin结构比较特殊,使用了宏定义来实现Plugin接口。MAIN()宏调用gimp_main、使得Plugin可以被Gimp调用,Gimp的Plugin接口比较简单,在gimp启动时将查询所有的Plugin并注册到一个PDB(proceduraldatabase)中,每个Plugin只需要实现下面的结构:

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论