繁体   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