2014-02-05 51 views
1

我正在開發一個項目,該項目應該能夠在運行時通過dlopen加載動態鏈接庫。使用動態鏈接庫管理堆

核心框架已經完成,它的確運轉良好,但我對如何正確管理庫中分配給堆的對象有一些懷疑。圖書館的接口有它返回一個指向庫內部靜態分配的對象,它是一類常見的有virtual方法亞型只有一個方法

來解釋它更好,我會提供我多麼希望存根它的工作原理:

// header common to the core and to the libraries 

class BaseSetting { 
.. 
} 

class DerivedSetting1 : public BaseSetting { .. } 
class DerivedSetting2 : public BaseSetting { .. } 

class ObjectInterface { 
    private: 
    vector<BaseSetting*> settings; 

    protected: 
    void registerSetting(Setting *setting) { settings.push_back(setting); } 

    public: 
    vector<Setting*> *getSettings() { return &settings; } 
} 

// library example 

class ConcreteObject { 
    ConcreteObject() { 
    registerSetting(new ..); 
    registerSetting(new ..); 
    } 

static ConcreteObject object; 

extern "C" ConcreteObject *retrieve() { return &object; } 

這裏的主要問題是我應該如何管理庫的堆分配設置?我需要多態性,所以我不能只存儲矢量內的具體對象,同時我需要在需要時通過卸載當前庫,並釋放與它們關聯的所有內存來在庫之間切換。我可以使用unique_ptr,但是這會讓事情變得複雜,因爲我只能通過get()獲得原始指針,然後破壞任何所有權,從而可以使用它們。

是否有共同的設計模式來處理這種情況?

回答

0

看看附件thismodule.ccclient.cc是動態加載到共享上下文中的外部對象,並彼此協作,app.cc是使其看起來相關聯的魔力C++。他們被構建/破壞的方式是您可能認爲適合您的問題的方式。

實質上,每種可插拔類型應該從通用接口bootstrap_ifc繼承,並且有兩種方法可以從共享庫中獲得已知接口。

extern "C" bootstrap_ifc* client_constructor() 
{ 
    return new(std::nothrow) client; 
} 

extern "C" void client_destructor(bootstrap_ifc* obj) 
{ 
    delete obj; 
} 
1

該解決方案是不是真的涉及到動態鏈接 - 問題及其解決方法是一樣的物體是否來自一個共享庫或者是主要的應用程序,從基類派生類的一部分。動態庫唯一的「額外」問題是,你顯然不能使用dlclose,同時仍然擁有駐留在動態庫中的代碼創建的活動對象(除非您100%確定任何東西都不會調用DL中的任何代碼,當然)。

你ObjectInterface需要具有刪除元素settings析構函數,

另外,您將需要有一個unregisterSetting被稱爲適合的地方(例如一些析構函數)。

-1

你可以寫一個代表你的庫的單例(你可以使用singulatiry庫)。在這個包裝的構造函數中,您將調用dlopen並在析構函數中dlclose +刪除所有分配的對象。 或者你想要簡單的東西 - 只需實現函數init和destroy並按照正確的順序調用它們: dlopen - > init - >使用庫 - > destroy - > dlclose