分享
 
 
 

Linux下插件开发应用案例

王朝system·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

在Linux 上愈来愈多的应用程序利用Plugin编程技术来实现扩展功能,目前应用比较广泛的有Gimp、Netscape/Mozilla、XMMS和Nessus等,本文将简单介绍这些软件的Plugin的架构和编程。

软件以生命力的Plugin

众所周知,要让一个软件具有生命力,最重要的一点是要让它提供并支持越来越多的功能,而这一点单凭开发者自身是很难独立做到的,需要让第三方的软件开发者可以通过作者提供的一种途径来为该软件添加功能。

最初,人们是使用关联模式,也就是像Windows下的文件扩展名一样,根据不同的文件关联,使用不同的软件打开相应的文件。这种方式编写扩展最为容易和自由,但是存在一定的缺陷,首先是不能利用宿主软件的资源,其次是软件的界面风格不易统一、灵活性不好。后来出现了Plugin结构,也就是利用动态连接库的方式制作Plugin(在Windows平台下是DLL、在Linux/Unix环境下是share object library),Plugin程序只能依附于宿主程序运行,不能独立运行,使用Plugin的优点是系统开销小、速度快,同宿主程序结合紧密、灵活性好。

在Linux上,最著名的Plugin架构就是Netscape提出的Plugin架构,比较出名的还有WinAmp(www.winamp.com)(在Linux 上改名叫XMMS,网址为www.xmms.org),这个MP3 播放软件中多彩多姿的插件(Plugin)系统和皮肤(skin)系统为其一统天下做出了不可磨灭的贡献。现在WinAmp已开始提供一个NSDN(Null Soft Develop Network)来让大家开发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/Plugins

Netscape会自动搜寻这些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 __cplusplus

extern "C" {

#endif

class CPlugMain

{

public:

virtual int Action() = 0;

};

// 下面是Plugin的通用函数,每个Plugin都会重载这个函数,主程序将创建惟一的子进程

extern CPlugMain CreatePlug();

typedef CPlugMain  (CREATEPLUG_PROC)();

#ifdef __cplusplus

}

#endif //#define cplusplus

#endif //#define _PLUG_MAIN_H_



Plugin_main.cpp

#include "Plugin_main.h"

#include <stdio.h>

#include <dlfcn.h> //动态链接库相关函数

//下面将定义固定的Plugin名称,读者可以自行定义如同Windows注册表那样的Plugin注册系统

#define NUM_PLUGINS 2

char  szPlugins[] =

{

"./Plugin1.so",

"./Plugin2.so"

};

int main( int argc, char  argv )

{

CREATEPLUG_PROC createproc[NUM_PLUGINS];

CPlugMain  pPlugins[NUM_PLUGINS];

void  handle[NUM_PLUGINS];

char  error;

int i;

// 加载所有Plugin

for ( i=0; i<NUM_PLUGINS; i++ )

{

printf( "加载Plugin %s.\n", szPlugins[i] );

// 加载Plugin动态链接库

if (NULL == (handle[i] = dlopen( szPlugins[i], RTLD_LAZY )))

{

handle[i] = NULL;

printf( "dlopen error (%s)\n", szPlugins[i] );

}

else

{

// 取得CreatePlug的地址

createproc[i] = (CREATEPLUG_PROC)dlsym( handle[i], "CreatePlug" );

if ((error = dlerror()) != NULL)

{

dlclose( handle[i] );

handle[i] = NULL;

printf( "dlsym error (%s)\n", szPlugins[i] );

}

else

{

// 创建Plugin进程

pPlugins[i] = createproc[i]();

}

}

}

// 执行Plugin的动作

printf( "正在运行Plugin ..\n" );

for ( i=0; i<NUM_PLUGINS; i++ )

{

if (handle[i] != NULL)

{

pPlugins[i]->Action();

}

}

// 关闭Plugin

for ( i=0; i<NUM_PLUGINS; i++ )

{

if (handle[i] != NULL)

{

dlclose( handle[i] );

handle[i] = NULL;

}

}

return 0;

}



下面是一个最简单的Plugin,只包含了Plugin_main.h 这个头文件,并且实现Action和CreatePlug这两个函数。源程序如下:

Plugin_1.h

#ifndef _PLUGIN_1_H_

#define _PLUGIN_1_H_

#include ″Plugin_main.h″

class CPlugin1  public CPlugMain

public

virtual int Action



#endif //#define _PLUGIN_1_H_

Plugin_1.cpp

#include ″Plugin_main.h″

#include ″Plugin1.h″

#include <stdio.h>

int CPlugin1Action

printf( "这是Plugin 1,运行正常\n" );

return 0;

}

CPlugMain  CreatePlug()

{

return new CPlugin1;

}

}



值得注意的是,编译这个Plugin的时候要使用 -shared参数来产生动态链接库.so文件,例如:gcc -o Plugin1.so Plugin1.o -shared。

Plugin开发实战

我们来看看如何为现有的一些软件编写Plugin,其中最复杂的是Netscape 4.x 和Mozilla (Netscape 6.x)的Plugin编写工作,而Xmms/Gimp/Nessus的Plugin相对来说要容易编写得多。

1. Netscape 4.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需要实现的工作包括以下内容:

(1)登记一种或几种Plugin要操作的MIME格式;

(2)在浏览器的窗口中间绘图;

(3)接收鼠标/键盘输入;

(4)从相应的URL中下载/发送数据。

用户如果要开发Netscape的Plugin,首先要在ftp://ftp.netscape.com/pub/sdk/Plugin/unix

下载相应的SDK 文件,里面有简单的例子,用户可以自行修改成自己的Plugin。

Mozilla/Netscape 6.x的Plugin架构是目前最先进的一种,它主要有下列优点:

(1)提供基于C++的API函数;

(2)提供了XPCOM,它是COM (the Component Object Model)的一个子集,XP的意思是cross-platform(跨平台),这使得新的Plugin的跨平台性和不同版本的兼容性得到了极大的提高;

(3)完全向后兼容,所有老的4.x 系列的Netscape Plugin 都可以继续使用。

Mozilla 的Plugin架构将原来的NPP 系列接口改变为:NPIPlugin、 NPIPluginInstance和NPIPluginStream 三个类;NPN 系列接口被扩充为NPIPluginManager、NPIPluginManagerStream、NPIPluginInstancePeer和NPIPluginStreamPeer

四个类,其中NP的意思是Netscape Plugin, I的意思是Interface。

linux插件开发参考文献 xmms插件开发指南: http://www.xmms.org

gimp插件开发指南: http://www.gimp.org/plugin_devel.html

nessus插件开发指南: http://www.nessus.org/doc/plugins_api.txt

http://www.nessus.org/doc/nasl.html

netscape 4.x 系列插件开发指南:

http://developer.netscape.com/docs/manuals/

communicator/plugin/index.htm

ftp://ftp.netscape.com/pub/sdk/plugin/unix

mozilla netscape 6.x系列插件开发指南:

http://www.doczilla.com/development/extmoz.html

http://www.mozilla.org/docs/

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有