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

cyt
VC里面實現動態對象載入已經不是什么新鮮事情了,很多的plug-in技術就是例子。Unix下,通過動態載入so獲得一個對象也不是什么難事,不過對這個對象的管理就是一件比較麻煩的事情了。一般的需求如下:
??有class TMyObj,準確說TMyObj應該是一個接口,根據不同具體情況會有不同的實現,例如 TMyObj1、TMyObj2等等……而這些TMyObj1和TMyObj2分別保存在不同的so當中,需要根據不同的時候load不同的so,建立相應的對象。由于這些對象都擁有TMyObj的接口,所以對于外部來說對這些類的使用就像對TMyObj的使用一樣。
??看起來好像比較簡單,只要在so里面引出一個函數:
??TMyObj * onCreateObject(void);
??而函數在so中的具體實現就是建立不同的子類,例如在obj1.so中:
??TMyObj * onCreateObject(void)
???{?return new TMyObj1;?}
??使用的時候只需要動態load入obj1.so,并且找到onCreateObject函數的入口,就可以建立一個具有TMyObj接口的TMyObj1了。
??至于釋放對象,一般有兩種方法:
方法一:
??so中包含另外一個函數:
??void onDestroyObj(void * p)
??{
????TMyObj1 * tp = (TMyObj1 *)p;
????delete tp;
??}
??從so中導出該函數,并在刪除對象的時候調用。
方法二:
??TMyObj的析構函數聲明為虛函數,那么從so導出的onCreateObject()建立的對象,直接執行delete刪除就行了,由于析構函數是虛函數,編譯器會正確的調用TMyObj1的析構函數。
??當然,方法二是比較簡單而優雅的方法,既然對于C++來說接口就相當于純虛函數,多增加一個析構的虛函數又何妨呢。但是無論使用哪種方法,都要注意一個問題,就是載入的obj1.so的生命周期要比最后一個TMyObj1的生存周期長。即只要內存中還存在TMyObj1對象,obj1.so就要一直在內存中,不能卸載。要保證這個同步,是比較麻煩的事情。下面就說說我的解決方法:
??
??首先,要選擇一個通用的載入so的lib,這個可以參考一下common c++的DSO(在file.h)里面。(不想使用common c++?我也只是說“參考”而已)。這個支持DLL和so,通過成員函數void *operator[](const char *);獲得指定的symbol的入口。
??其次,就要選擇一個通用的SmartPtr。這個當然Loki是首選,Loki的SmartPtr的靈活性比boost的smart_ptr強多了,而且Loki也小巧的多。
??然后就要實現一個簡單的so的manager,其實應該說是一個動態object的factory:
??class TObjFactory : protected DSO
??{
??public:
????TObjFactory(void);
????
????void?load(const std::string & strPath);
????void *?createObj(void) const throw (TSOException);
??protected:
????typedef void * (*funcCreate)(void ** p);
????funcCreate??m_pCreator;
??};
??可以想象這個類干些什么:load就是載入相應的so,然后獲得so中onCreateObject函數的入口,并賦給成員m_pCreator。而createObj就是調用m_pCreator建立對象。不過有所不同的是 m_pCreator所指向的函數形式是void * funcCreate(void ** p),而多出來void **p用處就是可以讓so中的構造函數中產生的exception能夠傳遞出來。這個不能說不是so的麻煩之處,so中函數的exception不能被外部捕獲,所以只好這樣子做了。
??現在,關鍵的地方來了,就是要保證這個TObjFactory的生存周期了。選擇Loki的SmartPtr就能派上用場了。
??Loki的SmartPtr可以自己選定適用的StoragePolicy,這正是我們需要的,參考DefaultSPStorage,可以做我們的TMySOStoragePolicy:
??template
???class TMySOStoragePolicy
???{
????.....
???protected:
????void Destroy()
??????? {
??????? ?delete pointee_;
??????? ?m_pFactory = SmartPtr();
??????? }???
???private:
????SmartPtr?m_pFactory;
????StoredType ??????pointee_;
???};
??顯而易見,這樣做的目的就是要保證釋放指針的時候就減少TObjFactory的引用計數。
??好了,現在就是主角了:
??template
??class TDObj : public SmartPtr
??{
??public:
????TDObj(void);
????TDObj(const TDObj & obj);
????.....
????
??protected:
????friend class TDObjManager;
????TDObj(T * p, SmartPtr pManager);
??};
??
??class TDObjManager
??{
??public:
????......
????template
?????static TDObj??createObj(const std::string & strKeyName)
?????{
???????SmartPtr pFactory = getFactoryByName(strKeyName);
???????//這里面可以做很多事情了,例如訪問內存,查找相應的Factory;或者讀取配置文件、讀入新的so并建立新的Factory。
???????//或者根據一些淘汰算法,先淘汰內存的Factory,然后重新載入新的Factory等等。
???????std::auto_ptr _au( static_cast(pFactory->createObj()) );
???????return TDObj( _au.release(), pFactory);
?????}
??};
??
??以后用起來就簡單多了:
??class TMyObj
??{
??public:
???virtual ~TMyObj(void);
???virtual int func(void) = 0;
??};
??
??TDObj?obj1 = TDObjManager::createObj( "obj1.so") );
??TDObj?obj2 = TDObjManager::createObj( "obj2.so") );
??
??cout << obj1->func() << endl;
??cout << obj2->func() << endl;

??說了這么久,都是主程序的調用,而so中應該如何呢?其實也很簡單:
??class TMyObj1 : public TMyObj
??{
??public:
????TMyObj1(void);
????~TMyObj1(void);

????static void?onStaticInit(void);
????static void?onStaticDestroy(void);
????static const char *?getVersion(void);
????static const char *?getObjectName(void);
????
????virtual int??func(void);
??};
??
??DECLARE_SO_INTERFACE(TMyObj1);
??
??DECLARE_SO_INTERFACE其實是一個為了方便編寫程序而定義的宏:
??#define DECLARE_SO_INTERFACE(x)?extern "C" {?\
????void onInstallDLL(void);???\
????void onUninstallDLL(void);???\
????const char * onGetVersion(void);?\
????const char * onObjectName(void);?\
????void *?onCreateObject(void ** ppException);??\
???}; \
???void?onInstallDLL(void)?{ x::onStaticInit(); }????\
???void?onUninstallDLL(void)?{ x::onStaticDestroy(); }??\
???const char * onGetVersion(void) { return x::getVersion(); }??\
???const char * onObjectName(void)?{ return x::getObjectName(); }?\
???void *?onCreateObject(void ** pException)?{?\
????try { \
?????*pException = NULL; x * p = new x();?return (void *)p; \
????}catch(std::exception & e) { \
?????*pException = new std::exception(e); \
?????return NULL; ?\
????}?\
???}
???
??可以看到除了導出onCreateObject函數以外,還導出了:
??TMyObj1::onStaticInit用于載入so的時候執行初始化操作;
??TMyObj1::onStaticDestroy用于卸載so的時候執行清理操作;
??TMyObj1::getVersion?獲得對象的版本信息
??TMyObj1::onObjectName 獲得對象名信息等
??可以擴展前面的TObjFactory,實現這些功能。

??同理,我們可以做obj2.so:
??class TMyObj2 : public TMyObj
??{
??public:
???TMyObj2(void);
???~TMyObj2(void);
??
???static void?onStaticInit(void);
???static void?onStaticDestroy(void);
???static const char *?getVersion(void);
???static const char *?getObjectName(void);
??
???virtual int??func(void);
??};
??
??DECLARE_SO_INTERFACE(TMyObj2);
??
??
??另外,一個值得討論的問題是:C++由于沒有反射機制,所以無法實現設值注入和構造注入,只能實現接口注入。不過一般來說也已經足夠使用了。

posted on 2005-10-08 14:51 cyt 閱讀(1288) 評論(2)  編輯 收藏 引用
Comments
  • # re: C++實現動態載入對象
    小明
    Posted @ 2005-11-28 13:12
    跟Java比較,C++真的很無奈阿

    要用丑陋的macro.

    Spring那么偉大的framework,卻沒有辦法在C++做到。  回復  更多評論   
  • # re: C++實現動態載入對象
    數據恢復
    Posted @ 2006-03-29 23:22

      回復  更多評論   
 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美精品性视频| 日韩午夜电影av| 欧美在线电影| 欧美一级理论片| 国产日韩欧美精品综合| 亚洲一区视频在线观看视频| 亚洲无玛一区| 国产视频在线观看一区 | 亚洲欧美韩国| 国产日韩欧美在线视频观看| 欧美成人激情在线| 欧美激情一二区| 亚洲手机在线| 欧美一区=区| 亚洲精品日韩综合观看成人91| 亚洲国产三级| 欧美色图一区二区三区| 午夜亚洲影视| 欧美成人午夜视频| 欧美亚洲综合网| 蜜臀久久99精品久久久久久9| 亚洲九九精品| 欧美一区亚洲| 一本色道久久综合精品竹菊 | 亚洲字幕一区二区| 亚洲国产精品综合| 国产精品99久久久久久宅男 | 亚洲高清色综合| 一卡二卡3卡四卡高清精品视频| 国产人成精品一区二区三| 欧美国产精品v| 国产精品久久九九| 亚洲国产99精品国自产| 国产老肥熟一区二区三区| 欧美成人免费小视频| 欧美亚韩一区| 亚洲国产日韩欧美| 国产一区二区三区直播精品电影 | 久久综合国产精品| 亚洲福利视频二区| 亚洲日本成人| 夜夜精品视频一区二区| 黄色日韩网站视频| 一本不卡影院| 亚洲精品综合精品自拍| 久久av一区二区三区亚洲| 亚洲激情专区| 久久久久久婷| 久久精品在线视频| 国产精品久久久久久久久久免费| 欧美国产精品中文字幕| 国产精品三上| 日韩视频免费观看高清在线视频 | 亚洲视频axxx| 欧美~级网站不卡| 美女脱光内衣内裤视频久久网站| 久久久国产精品亚洲一区| 国产精品理论片| 亚洲一区二区三区免费视频| 一区二区免费在线视频| 欧美激情第三页| 国产精品久久久久一区二区三区 | 欧美一区=区| 亚洲国产欧美一区二区三区久久 | 欧美成人一区二区三区| 国产一区再线| 久久精品欧洲| 蜜臀va亚洲va欧美va天堂| 狠狠综合久久av一区二区老牛| 亚洲精品视频在线看| 日韩亚洲欧美在线观看| 欧美成人福利视频| 欧美国产先锋| 亚洲精品视频在线播放| 欧美成人亚洲| 日韩视频在线观看国产| 亚洲一区免费观看| 欧美精品色网| 中国成人黄色视屏| 欧美在线视频在线播放完整版免费观看| 欧美日韩理论| 午夜在线视频观看日韩17c| 久久九九99| 亚洲国产老妈| 欧美手机在线视频| 午夜伦理片一区| 欧美电影免费观看网站| 亚洲精品一品区二品区三品区| 欧美理论大片| 亚洲欧美中文字幕| 欧美fxxxxxx另类| 亚洲少妇中出一区| 国内精品免费午夜毛片| 欧美aaaaaaaa牛牛影院| 一区二区三区不卡视频在线观看| 欧美一区二区三区日韩| 亚洲第一二三四五区| 欧美色区777第一页| 午夜一区二区三区在线观看| 麻豆九一精品爱看视频在线观看免费| 亚洲人成在线影院| 国产乱码精品| 嫩草伊人久久精品少妇av杨幂| av成人动漫| 欧美xxx在线观看| 亚洲一区亚洲二区| 亚洲春色另类小说| 国产麻豆精品theporn| 久久蜜桃精品| 亚洲免费影视第一页| 亚洲电影中文字幕| 久久精品国产69国产精品亚洲 | 中日韩美女免费视频网址在线观看 | 欧美午夜不卡在线观看免费| 欧美在线免费观看亚洲| 亚洲精品国产视频| 久久亚洲私人国产精品va| 亚洲视频专区在线| 亚洲欧洲综合另类在线| 国产一区二区毛片| 国产精品久久久久9999吃药| 免费亚洲网站| 久久精品国产综合精品| 亚洲一线二线三线久久久| 亚洲国产精品999| 免费国产一区二区| 久久精品免费电影| 欧美淫片网站| 午夜亚洲性色视频| 一区二区三区福利| 亚洲美女在线一区| 亚洲精品小视频| 91久久久久久国产精品| 国外成人在线视频网站| 国产欧美精品一区二区色综合 | 国产麻豆午夜三级精品| 欧美色图首页| 欧美日韩亚洲精品内裤| 欧美精品亚洲| 欧美经典一区二区三区| 欧美国产日韩精品免费观看| 久久综合一区二区| 狂野欧美激情性xxxx欧美| 久久久夜夜夜| 免费不卡中文字幕视频| 农夫在线精品视频免费观看| 噜噜噜91成人网| 免费欧美日韩| 欧美精品xxxxbbbb| 欧美看片网站| 国产精品丝袜xxxxxxx| 国产精品视频yy9099| 国产精品视频免费在线观看| 国产精品色网| 韩国女主播一区| 亚洲福利专区| 99精品国产热久久91蜜凸| 亚洲午夜国产一区99re久久| 亚洲永久免费观看| 久久精品国产v日韩v亚洲| 久久精品九九| 亚洲级视频在线观看免费1级| 91久久久久久久久| 亚洲——在线| 久久久蜜臀国产一区二区| 麻豆亚洲精品| 国产精品久久久久久久久| 国产日韩精品入口| 亚洲高清视频一区二区| 99视频一区| 久久精品成人一区二区三区| 欧美成人精品在线| 中文日韩在线视频| 久久精品久久综合| 欧美人与禽猛交乱配| 国产日产欧美一区| 亚洲国产欧美一区| 欧美伊人久久| 亚洲精品日韩激情在线电影 | 欧美激情中文字幕在线| 一本久道久久综合狠狠爱| 久久视频在线看| 亚洲日本精品国产第一区| 午夜精品一区二区三区四区| 免费在线欧美黄色| 国产精品日日摸夜夜摸av| 91久久在线播放| 香蕉久久a毛片| 91久久精品美女高潮| 欧美一级夜夜爽| 欧美色图五月天| 亚洲人成人77777线观看| 欧美在线不卡视频| 日韩视频久久| 蜜乳av另类精品一区二区| 国产精品入口尤物| 亚洲视频中文| 亚洲肉体裸体xxxx137| 久久久美女艺术照精彩视频福利播放 | 久久亚洲私人国产精品va|