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

牽著老婆滿街逛

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

UNIX下C++實現(xiàn)動態(tài)載入對象

  VC里面實現(xiàn)動態(tài)對象載入已經(jīng)不是什么新鮮事情了,很多的plug-in技術(shù)就是例子。Unix下,通過動態(tài)載入so獲得一個對象也不是什么難事,不過對這個對象的管理就是一件比較麻煩的事情了。一般的需求如下:
  有class TMyObj,準確說TMyObj應該是一個接口,根據(jù)不同具體情況會有不同的實現(xiàn),例如 TMyObj1、TMyObj2等等……而這些TMyObj1和TMyObj2分別保存在不同的so當中,需要根據(jù)不同的時候load不同的so,建立相應的對象。由于這些對象都擁有TMyObj的接口,所以對于外部來說對這些類的使用就像對TMyObj的使用一樣。
  看起來好像比較簡單,只要在so里面引出一個函數(shù): 

TMyObj * onCreateObject(void);


  而函數(shù)在so中的具體實現(xiàn)就是建立不同的子類,例如在obj1.so中:

  TMyObj * onCreateObject(void)
   
return new TMyObj1; }


  使用的時候只需要動態(tài)load入obj1.so,并且找到onCreateObject函數(shù)的入口,就可以建立一個具有TMyObj接口的TMyObj1了。
  至于釋放對象,一般有兩種方法:
方法一:
  so中包含另外一個函數(shù):

  void onDestroyObj(void * p)
  
{
    TMyObj1 
* tp = (TMyObj1 *)p;
    delete tp;
  }


  從so中導出該函數(shù),并在刪除對象的時候調(diào)用。
方法二:
  TMyObj的析構(gòu)函數(shù)聲明為虛函數(shù),那么從so導出的onCreateObject()建立的對象,直接執(zhí)行delete刪除就行了,由于析構(gòu)函數(shù)是虛函數(shù),編譯器會正確的調(diào)用TMyObj1的析構(gòu)函數(shù)。
  當然,方法二是比較簡單而優(yōu)雅的方法,既然對于C++來說接口就相當于純虛函數(shù),多增加一個析構(gòu)的虛函數(shù)又何妨呢。但是無論使用哪種方法,都要注意一個問題,就是載入的obj1.so的生命周期要比最后一個TMyObj1的生存周期長。即只要內(nèi)存中還存在TMyObj1對象,obj1.so就要一直在內(nèi)存中,不能卸載。要保證這個同步,是比較麻煩的事情。下面就說說我的解決方法:
  
  首先,要選擇一個通用的載入so的lib,這個可以參考一下common c++的DSO(在file.h)里面。(不想使用common c++?我也只是說“參考”而已)。這個支持DLL和so,通過成員函數(shù)void *operator[](const char *);獲得指定的symbol的入口。
  其次,就要選擇一個通用的SmartPtr。這個當然Loki是首選,Loki的SmartPtr的靈活性比boost的smart_ptr強多了,而且Loki也小巧的多。
  然后就要實現(xiàn)一個簡單的so的manager,其實應該說是一個動態(tài)object的factory:

class TObjFactory : protected DSO
  
{
  
public:
    TObjFactory(
void);
    
    
void load(const std::string & strPath);
    
void * createObj(voidconst throw (TSOException);
  
protected:
    typedef 
void * (*funcCreate)(void ** p);
    funcCreate  m_pCreator;
  }
;


  可以想象這個類干些什么:load就是載入相應的so,然后獲得so中onCreateObject函數(shù)的入口,并賦給成員m_pCreator。而createObj就是調(diào)用m_pCreator建立對象。不過有所不同的是 m_pCreator所指向的函數(shù)形式是void * funcCreate(void ** p),而多出來void **p用處就是可以讓so中的構(gòu)造函數(shù)中產(chǎn)生的exception能夠傳遞出來。這個不能說不是so的麻煩之處,so中函數(shù)的exception不能被外部捕獲,所以只好這樣子做了。
  現(xiàn)在,關(guān)鍵的地方來了,就是要保證這個TObjFactory的生存周期了。選擇Loki的SmartPtr就能派上用場了。
  Loki的SmartPtr可以自己選定適用的StoragePolicy,這正是我們需要的,參考DefaultSPStorage,可以做我們的TMySOStoragePolicy:

template<class T>
   
class TMySOStoragePolicy
   
{
    ..
   
protected:
    
void Destroy()
        

         delete pointee_;
         m_pFactory 
= SmartPtr<TObjFactory>();
        }
   
   
private:
    SmartPtr
<TObjFactory> m_pFactory;
    StoredType       pointee_;
   }
;

  顯而易見,這樣做的目的就是要保證釋放指針的時候就減少TObjFactory的引用計數(shù)。
  好了,現(xiàn)在就是主角了:
  

template<class T>
  
class TDObj : public SmartPtr<T,RefCounted,DisallowConversion,AssertCheck,TMySOStoragePolicy>
  
{
  
public:
    TDObj(
void);
    TDObj(
const TDObj & obj);
    ..
    
  
protected:
    friend 
class TDObjManager;
    TDObj(T 
* p, SmartPtr<TObjFactory> pManager);
  }
;
  
  
class TDObjManager
  
{
  
public:
    
    template
<class T>
     
static TDObj<T>  createObj(const std::string & strKeyName)
     
{
       SmartPtr
<TObjFactory> pFactory = getFactoryByName(strKeyName);
       
//這里面可以做很多事情了,例如訪問內(nèi)存,查找相應的Factory;或者讀取配置文件、讀入新的so并建立新的Factory。
       
//或者根據(jù)一些淘汰算法,先淘汰內(nèi)存的Factory,然后重新載入新的Factory等等。
       std::auto_ptr<T> _au( static_cast<*>(pFactory->createObj()) );
       
return TDObj<T>( _au.release(), pFactory);
     }

  }
;

  
  以后用起來就簡單多了:
  

class TMyObj
  
{
  
public:
   
virtual ~TMyObj(void);
   
virtual int func(void= 0;
  }
;
  
  TDObj
<TMyObj> obj1 = TDObjManager::createObj<TMyObj>"obj1.so") );
  TDObj
<TMyObj> obj2 = TDObjManager::createObj<TMyObj>"obj2.so") );
  
  cout 
<< obj1->func() << endl;
  cout 
<< obj2->func() << endl;


  說了這么久,都是主程序的調(diào)用,而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(voidreturn x::getVersion(); }  \
   
const char * onObjectName(voidreturn 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函數(shù)以外,還導出了:
  TMyObj1::onStaticInit用于載入so的時候執(zhí)行初始化操作;
  TMyObj1::onStaticDestroy用于卸載so的時候執(zhí)行清理操作;
  TMyObj1::getVersion 獲得對象的版本信息
  TMyObj1::onObjectName 獲得對象名信息等
  可以擴展前面的TObjFactory,實現(xiàn)這些功能。

  同理,我們可以做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++由于沒有反射機制,所以無法實現(xiàn)設值注入和構(gòu)造注入,只能實現(xiàn)接口注入。不過一般來說也已經(jīng)足夠使用了。

posted on 2006-09-05 13:07 楊粼波 閱讀(846) 評論(0)  編輯 收藏 引用 所屬分類: 文章收藏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>
            欧美二区在线观看| 国产一区二区成人久久免费影院| 亚洲精品一二| 亚洲三级视频在线观看| 欧美激情精品久久久久久蜜臀 | 国产日韩欧美电影在线观看| 国产精品免费网站| 国产亚洲一区二区三区| 亚洲电影在线观看| 亚洲精品中文字| 欧美一级一区| 欧美大尺度在线观看| 99精品免费视频| 欧美一区日本一区韩国一区| 男女激情久久| 国产精品亚洲成人| 亚洲黄色影片| 欧美在线亚洲一区| 亚洲网站视频| 欧美韩国一区| 国产精品一区视频| 亚洲第一页中文字幕| 99热在线精品观看| 欧美主播一区二区三区美女 久久精品人| 久久九九全国免费精品观看| 欧美88av| 午夜性色一区二区三区免费视频| 麻豆久久婷婷| 国产日韩亚洲欧美精品| 日韩亚洲视频| 欧美va天堂在线| 亚洲一区二区精品| 欧美激情综合色| 国产自产精品| 欧美一区二区三区日韩视频| 亚洲精品乱码久久久久久蜜桃91| 欧美一区二区精品| 欧美丝袜一区二区| 亚洲精品精选| 美日韩精品免费观看视频| 亚洲一区二区在线播放| 欧美另类极品videosbest最新版本| 国产一区二区精品丝袜| 亚洲专区一区二区三区| 亚洲欧洲精品一区二区三区波多野1战4| 午夜欧美不卡精品aaaaa| 欧美日韩专区在线| 亚洲精品在线二区| 欧美成人精品一区| 久久高清福利视频| 国产欧美日韩免费看aⅴ视频| 在线综合亚洲欧美在线视频| 亚洲福利视频一区| 美脚丝袜一区二区三区在线观看| 国产综合婷婷| 久久亚洲精品一区二区| 久久精品成人| 亚洲二区视频| 亚洲国产精品一区在线观看不卡| 乱人伦精品视频在线观看| 永久免费毛片在线播放不卡| 美国成人直播| 裸体一区二区三区| 最近看过的日韩成人| 亚洲国产精品一区在线观看不卡| 免费在线视频一区| 亚洲免费观看视频| 亚洲深爱激情| 国产亚洲免费的视频看| 米奇777超碰欧美日韩亚洲| 久久综合亚州| 在线亚洲一区观看| 亚洲欧美日韩国产一区二区三区| 国产日韩精品视频一区二区三区| 久久国产一二区| 久久久亚洲国产天美传媒修理工| 狠狠色狠狠色综合日日tαg | 午夜精品久久久久久久久| 欧美丝袜第一区| 午夜免费日韩视频| 久久精品国产欧美亚洲人人爽| 伊人成综合网伊人222| 欧美激情精品久久久久久蜜臀 | 欧美久久电影| 亚洲欧美日韩综合aⅴ视频| 欧美在线视频二区| 亚洲人成在线播放网站岛国| av72成人在线| 国产综合18久久久久久| 欧美黄在线观看| 欧美三级黄美女| 久久久青草婷婷精品综合日韩| 美女性感视频久久久| 亚洲欧美国产毛片在线| 久久免费精品视频| 亚洲一区二区三区精品在线观看| 欧美怡红院视频| 一区二区三区蜜桃网| 久久成人精品| 亚洲一区二区三区在线播放| 久久久综合免费视频| 亚洲欧美日本另类| 久久婷婷国产麻豆91天堂| 亚洲一区二区精品在线观看| 久久久蜜桃一区二区人| 午夜久久黄色| 欧美日韩国产欧| 欧美v亚洲v综合ⅴ国产v| 国产美女精品视频| 亚洲开发第一视频在线播放| **性色生活片久久毛片| 亚洲欧美日韩精品久久| 宅男噜噜噜66一区二区66| 久久在线免费视频| 久久九九国产| 国产精品免费电影| 亚洲免费播放| 亚洲久久成人| 欧美aaa级| 免费在线亚洲| 精品成人一区二区三区四区| 午夜精品一区二区三区在线视| 亚洲一区bb| 欧美日韩一区免费| 最新国产拍偷乱拍精品 | 夜夜嗨一区二区三区| 巨乳诱惑日韩免费av| 久久在线观看视频| 韩国av一区二区三区在线观看 | 欧美日韩国产成人在线免费| 欧美激情女人20p| 亚洲国产精品嫩草影院| 毛片av中文字幕一区二区| 欧美jizz19性欧美| 国产一区二区三区四区五区美女 | 欧美国产欧美综合 | 欧美福利网址| 亚洲国产另类精品专区| 久久先锋影音| 欧美va亚洲va国产综合| 亚洲国产综合在线| 免费成人高清| 亚洲欧洲一区二区三区| 一区二区不卡在线视频 午夜欧美不卡在 | 99riav1国产精品视频| 亚洲一区成人| 国产精品日韩欧美一区| 亚洲欧美在线磁力| 久久久久久免费| 亚洲黄色片网站| 欧美久久九九| 亚洲欧美区自拍先锋| 久久视频国产精品免费视频在线| 国产一区白浆| 男女精品视频| 亚洲午夜久久久久久尤物 | 日韩视频一区二区三区| 欧美三级韩国三级日本三斤| 亚洲免费一在线| 蜜桃av久久久亚洲精品| 99riav久久精品riav| 国产精品视频导航| 久久精品日产第一区二区| 亚洲国产精品久久精品怡红院| 中文国产成人精品久久一| 国产女主播一区| 免费欧美日韩国产三级电影| 一区二区三区四区精品| 久久婷婷麻豆| 亚洲综合日本| 在线观看日韩国产| 国产精品久久久一本精品| 狂野欧美激情性xxxx| 中文欧美在线视频| 欧美成人自拍| 性18欧美另类| 日韩一级精品视频在线观看| 国产日韩一区| 国产精品白丝jk黑袜喷水| 久久夜色精品亚洲噜噜国产mv| 99视频热这里只有精品免费| 欧美va天堂在线| 久久国产视频网| 亚洲一区二区三区在线播放| 亚洲国产综合视频在线观看| 国产性猛交xxxx免费看久久| 欧美日韩精品在线| 老司机午夜精品| 欧美影院在线| 亚洲女爱视频在线| 一道本一区二区| 亚洲三级免费电影| 欧美黑人在线播放| 欧美α欧美αv大片| 久久久人人人| 久久免费午夜影院| 老司机午夜精品视频| 亚洲精品国久久99热| 西西裸体人体做爰大胆久久久| 国内外成人在线视频|