【问题标题】:Managing heap with dynamically linked libraries使用动态链接库管理堆
【发布时间】:2014-02-05 18:56:32
【问题描述】:

我正在开发一个项目,该项目应该能够在运行时通过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() 获取原始指针就可以从核心使用它们,这会破坏任何所有权。

是否有处理此类情况的通用设计模式?

【问题讨论】:

    标签: c++ c dynamic-linking


    【解决方案1】:

    解决方案实际上与动态链接无关——无论您的对象来自共享库还是作为来自基类的派生类作为主应用程序的一部分,问题及其解决方案都是相同的。动态库的唯一“额外”问题是,您显然不能使用dlclose,同时仍然拥有由驻留在动态库中的代码创建的活动对象(除非您 100% 确定 NOTHING 将调用DL,当然)。

    你的 ObjectInterface 需要有一个析构函数来删除settings 中的元素,

    或者,您需要有一个在合适的地方调用的unregisterSetting(例如一些析构函数)。

    【讨论】:

      【解决方案2】:

      查看this 的附件。 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;
      }
      

      【讨论】:

        【解决方案3】:

        您可以编写一个代表您的库的单例(您可以为此使用singulatiry 库)。在此包装器的构造函数中,您将调用 dlopen 并在析构函数中调用 dlclose + 删除所有已分配的对象。 或者你想要一些更简单的东西 - 只需实现函数 init 和 destroy 并以正确的顺序调用它们: dlopen -> 初始化 -> 使用库 -> 销毁 -> dlclose

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-03-19
          • 2013-12-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-13
          相关资源
          最近更新 更多