简体   繁体   English

使用动态链接库管理堆

[英]Managing heap with dynamically linked libraries

I'm working on a project which should be able to load dynamically linked libraries at runtime through dlopen . 我正在开发一个项目,该项目应该能够在运行时通过dlopen加载动态链接的库。

The core framework is finished and it is indeed working but I have some doubt about how to correctly manage objects allocated on the heap by the libraries. 核心框架已经完成并且确实可以正常工作,但是我对如何正确管理库在堆上分配的对象存有疑问。 The interface to the library has just one method which returns a pointer to an object statically allocated inside the library which is a subtype of a common class with virtual methods 库的接口只有一种方法,该方法返回指向库内部静态分配的对象的指针,该对象是带有virtual方法的通用类的子类型。

To explain it better I'll provide a stub of how I want it to work: 为了更好地解释它,我将提供一个我希望它如何工作的存根:

// 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; }

The main problem here is how I should manage the heap allocated settings of the library? 这里的主要问题是我应该如何管理库的堆分配设置? I need polymorphism so I can't just store concrete objects inside the vector and at the same time I need to switch between libraries when needed, by unloading the current with dlclose , and release all the memory associated with them. 我需要多态性,所以我不能只将具体对象存储在向量中,同时需要在需要时通过使用dlclose卸载当前电流并释放与它们关联的所有内存在库之间进行切换。 I could use an unique_ptr but this would complicates things because I'll be able to use them from the core just by getting the raw pointer through get() which then would break any ownership. 我可以使用unique_ptr但这会使事情复杂化,因为我可以通过从get()获取原始指针来从内核使用它们,这将破坏所有所有权。

Is there a common design pattern to handle such situations? 是否有通用的设计模式来应对这种情况?

The solution isn't really related to dynamic linking - the problem and its solution is the same whether your objects come from a shared library or is part of the main application as derived classes from a base-class. 该解决方案与动态链接并没有真正的联系-问题和解决方案都是相同的,无论您的对象来自共享库还是作为基础类派生类的主要应用程序的一部分。 The only "extra" problem with dynamic libraries is that you obviously can't use dlclose while still having active objects created by code that resides in the dynamic library (unless you are 100% sure NOTHING will call any of the code in the DL, of course). 动态库的唯一“额外”问题是,您显然无法使用dlclose而仍然具有由动态库中的代码创建的活动对象(除非您100%确定NOTHING将调用DL中的任何代码,当然)。

Your ObjectInterface needs to have a destructor that deletes the elements in settings , 您的ObjectInterface需要有一个析构函数,用于删除settings的元素,

Alternatively, you will need to have a unregisterSetting that is called somewhere suitable (eg some destructor). 另外,您将需要有一个在适当位置(例如某些析构函数)调用的unregisterSetting

Have a look at the attachment to this . 看一看在连接到这个 module.cc and client.cc are external objects dynamically loaded into a shared context and collaborating with each other, app.cc is the associated magic to make it look C++ . module.ccclient.cc是动态加载到共享上下文中并相互协作的外部对象, app.cc是使它看起来像C++的关联魔术。 The way they are constructed/destructed is what you may find appropriate for your problem. 您可能会发现它们适合于您的问题的构造/破坏方式。

In essence, each pluggable type is supposed to inherit from a common interface bootstrap_ifc and have two methods with known interface available from the shared library. 从本质上讲,每个可插入类型都应从公共接口bootstrap_ifc继承,并具有两个可从共享库获得的具有已知接口的方法。

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

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

You can write a singleton which represents your library (you may use singulatiry library for that). 您可以写一个表示您的库的单例(您可以为此使用库)。 In constructor of this wrapper you will call dlopen and in destructor dlclose + delete all allocated objects. 在该包装的构造函数中,将调用dlopen,在析构函数dlclose中,将删除所有分配的对象。 Or you want something simpler - just implement functions init and destroy and call them in proper order: dlopen -> init -> work with library -> destroy -> dlclose 或者,您想要更简单的方法-只需实现函数init并销毁并按正确的顺序调用它们即可:dlopen-> init->使用库-> destroy-> dlclose

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 动态链接库的问题 - problems with dynamically linked libraries 动态链接库中如何处理“外部”变量? - How 'extern' variables are handled in dynamically linked libraries? 将动态链接库合并为一个静态链接库 - Combine Dynamically Linked Libraries into one Statically Linked Library 静态链接的 libcurl 是否仍然使用动态链接的库? - Does a statically linked libcurl still use dynamically linked libraries? 动态链接库中静态变量的行为(C / C ++) - Behaviour of static variables in dynamically linked libraries (C/C++) 在运行时加载的C ++动态链接库-Poco / qmake - C++ Dynamically Linked Libraries loaded at runtime - Poco / qmake 调用FreeLibrary后为动态链接到相同版本CRT堆的DLL释放内存 - Releasing memory for DLL dynamically linked to CRT heap with the same version after calling FreeLibrary 用编程语言管理库和导入 - Managing libraries and imports in a programming language 静态链接到 VC++ 运行时,同时包含动态链接到它的静态库 - Linking to the VC++ runtime statically while including static libraries that linked to it dynamically 动态链接库上的 g++ 用户定义的全局 new 和 delete 运算符 - g++ user-defined global new and delete operators on dynamically linked libraries
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM