动态加载库中的类,并在关闭库后使用它

时间:2014-02-19 17:27:24

标签: c++ dynamic-linking

TL; DR:是否可以在运行时从库中加载类对象,关闭库然后将该对象用作“普通”对象(关闭后)?

我正在尝试使用某种“热插拔”功能实现插件系统。假设我的程序期望从其插件中获得doSomething()函数。我的想法是扫描文件系统中的特定文件夹中的任何库,提取函数然后关闭lib(在使用函数之前!)。这样,监视器线程可以只监视文件系统上的更改,并在发生更改时重置函数指针,从而可以“热插拔”插件。

我相信一旦关闭库,函数指针就会变为无效(是吗?)。因此,我的想法是让库返回一个具有所需功能的对象的副本。在这种情况下,我会在关闭它之前调用lib来创建对象,并在我的程序中保存对象的 copy 。但是,由于对象可以使用库的其他对象/函数,我不确定这是否可行,因为这些对象/函数不可用,是吗?

2 个答案:

答案 0 :(得分:4)

  1. 您无法复制对象并关闭库,因为只复制数据,而不复制这些对象的代码。而不是操作系统将库的代码加载到内存中,并且所有函数指针都指向此内存区域。如果操作系统卸载库会怎么样?

  2. 你可以实现这样的东西。您可以拥有一个Proxy对象,该对象包含指向当前加载的实现的指针。如果检测到新库,则可以加载新库,创建新实现的实例,删除旧的实现实例,关闭旧库。通过这种方式,您可以实现"热插拔"机制并避免共享库代码的问题。

  3. 如果选择第2项中描述的方法,请注意并发问题(如果在删除旧实现时但在指针更改之前调度了另一个线程会怎么样?)。

答案 1 :(得分:1)

对象是数据,而不是代码。对象的副本是数据的副本,但它仍然引用原始代码。卸载动态库后,其代码就会从内存中消失,任何仍然引用该代码的对象(即库提供的类型)在被要求执行成员函数时都会遇到麻烦(例如作为析构者)。

所以不,不可能卸载库并继续使用它的代码。