簡體   English   中英

使用動態鏈接庫管理堆

[英]Managing heap with dynamically linked libraries

我正在開發一個項目,該項目應該能夠在運行時通過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; }

這里的主要問題是我應該如何管理庫的堆分配設置? 我需要多態性,所以我不能只將具體對象存儲在向量中,同時需要在需要時通過使用dlclose卸載當前電流並釋放與它們關聯的所有內存在庫之間進行切換。 我可以使用unique_ptr但這會使事情復雜化,因為我可以通過從get()獲取原始指針來從內核使用它們,這將破壞所有所有權。

是否有通用的設計模式來應對這種情況?

該解決方案與動態鏈接並沒有真正的聯系-問題和解決方案都是相同的,無論您的對象來自共享庫還是作為基礎類派生類的主要應用程序的一部分。 動態庫的唯一“額外”問題是,您顯然無法使用dlclose而仍然具有由動態庫中的代碼創建的活動對象(除非您100%確定NOTHING將調用DL中的任何代碼,當然)。

您的ObjectInterface需要有一個析構函數,用於刪除settings的元素,

另外,您將需要有一個在適當位置(例如某些析構函數)調用的unregisterSetting

看一看在連接到這個 module.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;
}

您可以寫一個表示您的庫的單例(您可以為此使用庫)。 在該包裝的構造函數中,將調用dlopen,在析構函數dlclose中,將刪除所有分配的對象。 或者,您想要更簡單的方法-只需實現函數init並銷毀並按正確的順序調用它們即可:dlopen-> init->使用庫-> destroy-> dlclose

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM