青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴(yán)以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

linux下C++ 插件(plugin)實(shí)現(xiàn)技術(shù)

文章來(lái)源:http://masterdog.bokee.com/563395.html
?
?????應(yīng)用程序中使用插件技術(shù),有利于日后的版本更新、維護(hù)(比如打補(bǔ)丁)和功能擴(kuò)展,是一種很實(shí)用的技術(shù)。其最大的特點(diǎn)是更新插件時(shí)無(wú)需重新編譯主程序,對(duì)于一個(gè)設(shè)計(jì)良好的應(yīng)用系統(tǒng)而言,甚至可以做到業(yè)務(wù)功能的在線升級(jí)。本文介紹了linux下用C++實(shí)現(xiàn)插件的一個(gè)簡(jiǎn)單實(shí)例,希望能對(duì)大家有所啟發(fā)。

為了能做到更新插件時(shí)無(wú)需重新編譯主程序,要求主程序中定義的接口是定死的,而接口的實(shí)現(xiàn)被放到了具體的插件中,這樣主程序在運(yùn)行時(shí)刻將插件加載進(jìn)來(lái),就可以使用這些接口所提供的功能了。在面向?qū)ο蟮南到y(tǒng)中,各個(gè)功能模塊被封裝到類(lèi)中,因此在C++中實(shí)現(xiàn)插件技術(shù),就需要在主程序中提供基類(lèi),并為這些基類(lèi)定義明確的接口,然后在插件(動(dòng)態(tài)庫(kù)或共享庫(kù))中定義派生類(lèi),并實(shí)現(xiàn)基類(lèi)中所有的接口。

我們以計(jì)算多邊形面積為例,首先定義一個(gè)基類(lèi)CPolygon:

/* +******************************************************* */
/* +******************************************************* */
/* +******************************************************* */

/* ?polygon.h? */

#ifndef?__POLYGON_H__
#define ?__POLYGON_H__

#include?
< ?iostream? >

class ?CPolygon
{
public :

????CPolygon()
{}

????
virtual ? ~ CPolygon() {}

????
virtual ? double ?area( void )? const ? = ? 0 ;
}
;

#endif ?/*?__POLYGON_H__?*/

/* -******************************************************* */
/* -******************************************************* */
/* -******************************************************* */

注意基類(lèi)不一定是虛類(lèi)(有純虛函數(shù)的類(lèi)),但是接口一定要定義成虛函數(shù),因?yàn)樽罱K主程序是通過(guò)基類(lèi)指針
來(lái)調(diào)派生類(lèi)的接口函數(shù),另外如果基類(lèi)中有資源分配(new)的話,析構(gòu)函數(shù)一定要定義成虛的,否則不會(huì)被
調(diào)用,造成內(nèi)存泄漏。

接下來(lái)要定義派生類(lèi),并放到共享庫(kù)(triangle.so)中:

/* +******************************************************* */
/* +******************************************************* */
/* +******************************************************* */

/* ?triangle.h? */

#ifndef?__TRIANGLE_H__
#define ?__TRIANGLE_H__

#include?
" ?polygon.h? "
#include?
< ?iostream? >

class ?CTriangle?:? public ?CPolygon
{
public :

????
virtual ? double ?area( void )? const ;

}
;

#endif ?/*?__TRIANGLE_H__?*/


/* ?triangle.cpp? */

#include?
" triangle.h "

extern ? " C "
{
????
void ? * ?create()
????
{
????????
return ? new ?CTriangle;
????}


}


double ?CTriangle::area( void )? const
{
????std::cout?
<< ? " area?of?triangle " ? << ?std::endl;
????
return ? 0 ;
}


/* -******************************************************* */
/* -******************************************************* */
/* -******************************************************* */

其中定義了函數(shù)“create”用來(lái)創(chuàng)建CTriangle類(lèi)對(duì)象,該函數(shù)可讓主程序獲得CTriangle對(duì)象指針,從而
可以訪問(wèn)CTriangle類(lèi)對(duì)象。主程序通過(guò)調(diào)用dlsym獲取指向該函數(shù)的指針,需要指出的是,由于dlsym被
設(shè)計(jì)成c-style方式,因此調(diào)用c++定義的函數(shù)時(shí),需要加上extern "C"

那么主程序是如何調(diào)用共享庫(kù)的呢,代碼片段如下:

/* +******************************************************* */
/* +******************************************************* */
/* +******************************************************* */

typedef?CPolygon
* ?create_t();

void ? * ?handle? = ?dlopen( " triangle.so " ,?RTLD_LAZY);

if (? ! handle?)
{
?std::cerr?
<< ?dlerror()? << ?std::endl;
?exit(
1 );
}


create_t?
* ?create_triangle? = ?(create_t? * )dlsym(handle,? " create " );

CPolygon?
* ?pObj? = ?create_triangle();

if (? 0 ? != ?pObj?)
{
?pObj
-> area();
}


delete?pObj;

dlclose(handle);

/* -******************************************************* */
/* -******************************************************* */
/* -******************************************************* */

主程序通過(guò)dlopen打開(kāi)triangle.so,然后通過(guò)dlsym得到庫(kù)中的函數(shù)create指針,調(diào)用create后返回了
指向CTriangle類(lèi)對(duì)象的指針,類(lèi)型是CPolygon的,由于虛函數(shù)的多態(tài)性, pObj->area() 實(shí)際是調(diào)用
了CTriangle::area.

好了,插件技術(shù)就是這么簡(jiǎn)單,回顧一下實(shí)現(xiàn)過(guò)程:寫(xiě)一個(gè)基類(lèi),定義接口函數(shù),然后在共享庫(kù)中寫(xiě)
派生類(lèi),最后在主程序運(yùn)行時(shí)刻打開(kāi)共享庫(kù)(dlopen),并通過(guò)create函數(shù)得到指向新創(chuàng)建的派生類(lèi)
對(duì)象的指針,然后利用虛函數(shù)的多態(tài)性,調(diào)用派生類(lèi)的各種方法。


不過(guò)進(jìn)一步使用后你可能會(huì)發(fā)現(xiàn),這樣實(shí)現(xiàn)會(huì)有些問(wèn)題:

1. 每寫(xiě)一個(gè)派生類(lèi)就需要重寫(xiě)一個(gè)create函數(shù)

注意到CTriangle類(lèi)實(shí)現(xiàn)時(shí)定義的create函數(shù)必須返回 new CTriangle:

?

extern ? " C "
{
????
void ? * ?create()
????
{
????????
return ? new ?CTriangle;
????}


}

?

那么如果再建一個(gè)類(lèi)比如CRectangle, create函數(shù)必須重寫(xiě),返回 new CRectangle

這樣做一方面麻煩,另外CTriangle、CRectangle兩個(gè)類(lèi)不能放到同一個(gè)共享庫(kù)中,否則會(huì)編譯時(shí)刻
提示重復(fù)定義錯(cuò)誤。


2. 主程序無(wú)法判斷create函數(shù)返回的是哪個(gè)類(lèi)所創(chuàng)建的對(duì)象

當(dāng)只有一個(gè)基類(lèi)(CPolygon)時(shí)主程序當(dāng)然知道返回的是CPolygon派生類(lèi)的對(duì)象指針:
create_t * create_triangle = (create_t *)dlsym(handle, "create");
CPolygon * pObj = create_triangle();

假如有多個(gè)基類(lèi),根據(jù)這些基類(lèi)派生出不同類(lèi)型的類(lèi)時(shí),無(wú)法在主程序中判斷返回的是那個(gè)類(lèi)的對(duì)象。


3. 操作繁瑣

沒(méi)有一個(gè)統(tǒng)一的操作界面,實(shí)現(xiàn)共享庫(kù)的加載、卸載、派生類(lèi)對(duì)象的創(chuàng)建,特別是當(dāng)需要加載一個(gè)目錄
下所有的共享庫(kù)時(shí),感覺(jué)一個(gè)一個(gè)地加載太麻煩了,能不能批量加載呢。


通過(guò)動(dòng)態(tài)類(lèi)加載和建立Helper類(lèi)可以很好地解決上述問(wèn)題,其中dynclass.h/dynclass.cpp中實(shí)現(xiàn)了動(dòng)態(tài)
加載類(lèi)對(duì)象,pluginhelper.h/pluginhelper.cpp實(shí)現(xiàn)了Plugin Helper,具體細(xì)節(jié)見(jiàn)附件。


下面簡(jiǎn)單介紹一下使用步驟:


1. 首先定義基類(lèi)(CPolygon),方法同上

2. 在共享庫(kù)中實(shí)現(xiàn)派生類(lèi)

比如CTriangle:

/* +******************************************************* */
/* +******************************************************* */
/* +******************************************************* */

/* ?triangle.h? */

#ifndef?__TRIANGLE_H__
#define ?__TRIANGLE_H__

#include?
" ?polygon.h? "
#include??
< ?iostream? >

class ?CTriangle?:? public ?CPolygon
{
public :

????
virtual ? double ?area( void )? const ;

}
;

#endif ?/*?__TRIANGLE_H__?*/


/* ?triangle.cpp? */

#include?
" ?triangle.h? "
#include?
" ?dynclass.h? "

DYN_DECLARE(CTriangle);

double ?CTriangle::area( void )? const
{
????std::cout?
<< ? " area?of?triangle " ? << ?std::endl;
????
return ? 0 ;
}


/* -******************************************************* */
/* -******************************************************* */
/* -******************************************************* */


注意到此時(shí)派生類(lèi)的實(shí)現(xiàn)(triangle.cpp)中已沒(méi)有了那個(gè)討厭的create了,被我偷偷放到
dynclass.cpp中了:

extern ? " C "
{
????
void ? * ?createByClassName( const ? char ? * ?strClassName)
????
{
????????
return ?DYN_CREATE(strClassName);
????}

}


由于對(duì)任何派生類(lèi)而言,該函數(shù)的實(shí)現(xiàn)都一樣,因此只需要實(shí)現(xiàn)一次,對(duì)使用者是不可見(jiàn)的,達(dá)到
了從派生類(lèi)中拿走的目的。

另外增加了一個(gè)宏:DYN_DECLARE(CTriangle); 參數(shù)是類(lèi)名(這里用到了RTTI),每個(gè)派生類(lèi)對(duì)應(yīng)
一個(gè)這樣的宏,該類(lèi)就可以支持類(lèi)對(duì)象的動(dòng)態(tài)加載了,需要包含頭文件dynclass.h


2. 在主程序中如何使用

使用起來(lái)也非常簡(jiǎn)單,在主程序(main.cpp)中:

/* +******************************************************* */
/* +******************************************************* */
/* +******************************************************* */


#include?
" ?pluginhelper.h? "
#include?
" ?polygon.h? "



CPluginHelper?pluginHelper;

pluginHelper.Load(?
" ./plugin " ,? " *.so " ?);

CPolygon?
* ?pbase? = ?(CPolygon? * )pluginHelper.Create( " CTriangle " );

if (? 0 ? != ?pbase?)
{
????pbase
-> area();
}


delete?pbase;

pluginHelper.Unload(?
" ./plugin " ,? " *.so " ?);

/* -******************************************************* */
/* -******************************************************* */
/* -******************************************************* */

首先定義CPluginHelper對(duì)象,調(diào)用Load方法加載共享庫(kù),其中第一個(gè)參數(shù)是共享庫(kù)的路徑,第二
個(gè)參數(shù)是共享庫(kù)的名稱(chēng),共享庫(kù)名支持模式匹配,這里表示要加載./plugin目錄所有so共享庫(kù),
當(dāng)然也可以是某個(gè)具體的共享庫(kù)名。

隨后可以通過(guò)CPluginHelper::Create方法,根據(jù)類(lèi)名稱(chēng)創(chuàng)建該類(lèi)的對(duì)象,實(shí)現(xiàn)了參數(shù)化創(chuàng)建對(duì)象
的目的,然后就是對(duì)該對(duì)象的調(diào)用,當(dāng)不用該對(duì)象時(shí),需要調(diào)用delete來(lái)刪除。

最后,調(diào)用CPluginHelper::Unload將指定共享庫(kù)卸載。

http://masterdog.bokee.com/inc/20050116132524159116.zip

posted on 2006-08-26 04:37 楊粼波 閱讀(829) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): C++

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久人人九九| 欧美综合二区| 亚洲国产影院| 蜜桃伊人久久| 亚洲精品中文字幕在线观看| 亚洲精品之草原avav久久| 欧美精品一区二| 亚洲影视在线播放| 亚洲女优在线| 一区二区三区在线观看视频 | 欧美日韩大片一区二区三区| 一本色道久久综合精品竹菊 | 久久av一区二区三区亚洲| 欧美在线视频观看| 最新国产精品拍自在线播放| 亚洲日本激情| 国产精品一区视频网站| 噜噜噜在线观看免费视频日韩| 久久天堂av综合合色| 99视频在线精品国自产拍免费观看| 99v久久综合狠狠综合久久| 国产日本欧美一区二区三区| 欧美成人一区在线| 欧美午夜免费影院| 久久深夜福利| 欧美日韩综合精品| 老司机一区二区| 欧美性事在线| 欧美大秀在线观看| 国产精品网站一区| 亚洲成人中文| 国产午夜精品全部视频在线播放 | 久久精品91| 欧美理论电影网| 久久精视频免费在线久久完整在线看| 久久亚洲精品中文字幕冲田杏梨| 亚洲影视在线| 欧美高清视频www夜色资源网| 欧美在线亚洲综合一区| 欧美精品一区二区三区蜜桃| 久久亚洲私人国产精品va| 欧美视频一区二区| 欧美激情一区二区三区在线| 国产一区二区三区久久精品| 一区二区电影免费观看| 亚洲国产影院| 欧美在线在线| 欧美一进一出视频| 国产精品福利久久久| 亚洲人成亚洲人成在线观看| 极品裸体白嫩激情啪啪国产精品| 久久av一区二区| 国产综合香蕉五月婷在线| 一区二区激情视频| 亚洲欧洲一区| 蜜乳av另类精品一区二区| 久久国产精品久久久| 国产精品久久久久影院亚瑟| 亚洲人成高清| 亚洲免费av片| 欧美国产免费| 亚洲国产人成综合网站| 亚洲国产精品va在看黑人| 久久综合久久综合久久| 久久免费视频网站| 精品动漫一区| 久久亚洲综合色| 欧美va天堂| 亚洲欧洲日韩综合二区| 美女精品网站| 亚洲高清自拍| 一本色道久久综合亚洲精品婷婷 | 亚洲伦理自拍| 国产精品99久久久久久久vr| 欧美日韩一区二区在线 | 久久精品亚洲精品国产欧美kt∨| 国产精品免费视频xxxx| 亚洲欧美综合另类中字| 久久久国产成人精品| 在线欧美日韩国产| 欧美3dxxxxhd| av成人手机在线| 性欧美在线看片a免费观看| 国产精品中文字幕欧美| 久久国产精品第一页 | 一区二区三区日韩精品| 国产精品久久久久一区二区三区| 午夜精品一区二区三区四区| 久久综合九色欧美综合狠狠| 亚洲国产一区二区视频| 欧美视频一区二区三区四区| 亚洲一区欧美二区| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲国产毛片完整版| 欧美肉体xxxx裸体137大胆| 亚洲欧美中日韩| 男人的天堂亚洲| 国产精品99久久久久久久女警| 国产精品久久久久久亚洲毛片| 久久精品国产欧美激情| 亚洲欧洲精品一区二区精品久久久| 亚洲午夜女主播在线直播| 国产在线观看精品一区二区三区| 欧美激情精品久久久久| 亚洲综合精品| 亚洲国产欧美在线人成| 久久精品人人爽| 99re8这里有精品热视频免费| 国产欧美日韩视频在线观看| 欧美成人xxx| 午夜视频一区在线观看| 亚洲人成网站在线观看播放| 久久久久国色av免费看影院| 日韩写真视频在线观看| 国际精品欧美精品| 国产精品电影在线观看| 欧美黄免费看| 久久久欧美精品| 老司机亚洲精品| 欧美中文在线观看| 中日韩午夜理伦电影免费| 欧美成人亚洲| 久久综合色播五月| 欧美影院在线播放| 亚洲视频999| 在线免费高清一区二区三区| 国产精品一区二区三区四区 | 正在播放欧美视频| 亚洲欧洲精品一区二区三区不卡 | 午夜日韩在线观看| 99精品福利视频| 在线观看欧美一区| 国产一区二区剧情av在线| 国产精品白丝av嫩草影院| 欧美国产日本在线| 免费久久99精品国产| 性色av一区二区三区在线观看 | 久久精品日产第一区二区三区| 午夜激情亚洲| 亚洲图片你懂的| 一区二区三区视频在线| 亚洲高清自拍| 亚洲国产综合91精品麻豆| 黄色成人精品网站| 在线观看日韩欧美| 一区二区亚洲精品| 极品av少妇一区二区| 亚洲成人在线网| 亚洲二区精品| 亚洲欧洲偷拍精品| 99在线观看免费视频精品观看| 日韩视频精品| 一区二区三区国产精华| 国产精品99久久久久久人| 亚洲一区二区成人| 欧美一区二区三区免费视频| 久久成人精品| 久久免费视频这里只有精品| 欧美a一区二区| 欧美激情视频在线免费观看 欧美视频免费一 | 亚洲欧美日韩在线高清直播| 亚洲欧美自拍偷拍| 久久黄色小说| 免费亚洲一区| 最新中文字幕一区二区三区| 夜夜精品视频| 欧美伊久线香蕉线新在线| 久久久福利视频| 欧美国产日韩a欧美在线观看| 欧美日本亚洲视频| 国产精品青草综合久久久久99 | 久久一区视频| 欧美日韩精品免费观看视频| 国产精品五区| 雨宫琴音一区二区在线| 日韩亚洲欧美在线观看| 先锋影音网一区二区| 你懂的视频一区二区| 亚洲免费观看高清完整版在线观看| 亚洲视频在线看| 久久久亚洲欧洲日产国码αv | 日韩网站在线| 午夜一区二区三区在线观看| 欧美一区二区三区免费观看视频| 另类人畜视频在线| 一本久久综合| 久久久久久国产精品mv| 国产精品黄色在线观看| 亚洲电影av| 欧美怡红院视频| 亚洲精品乱码久久久久久久久| 午夜欧美理论片| 欧美日韩国产精品专区| 国内精品伊人久久久久av一坑| 中文日韩电影网站| 欧美电影在线观看完整版| 午夜精品久久久久久久久久久久久| 久热精品视频在线免费观看| 国产精品露脸自拍| 99天天综合性|