使用“dlopen”重新加载运行时库

Runtime library reloading using `dlopen`

基于 运行 c++ 的进程是否可以使用 dlopen 重新加载基于 c++ 的动态库。

运行 进程轮询动态库的新版本(与 API 相同)。一旦检测到此类文件,就会发生以下一组操作:

  1. 使用 dlclose
  2. 卸载旧库
  3. 复制较新的dylib并覆盖旧版本的文件。
  4. 该进程使用 dlopen
  5. 从该位置加载较新版本
  6. 根据dlsym从新加载的库中设置函数指针变量。

在最后阶段,我实际上得到了想要的 API 并将其放在我的主代码中的函数指针中,以备后用。

但是,好像我的程序在第三阶段之后意外崩溃了。 dlclose 部分是否可能在进程虚拟 space 中留下旧库的一些残余?有没有更好的方法呢?

顺便说一下,在 Windows 中使用 LoadLibrary, FreeLibrary and GetProcAddress 代替 dlopen, dlclose and dlsym 就可以正常工作。

it seems like my program is unexpectedly gets crashed after the third phase. is it possible that the dlclose part leave some remnants of the older library in the process virtual space?

有可能。具有指向函数的函数指针的对象和具有在要卸载的库中定义的虚函数的对象将以无效指针结束。更糟糕的是,可以将新的方面附加到标准流(例如 std::cout),然后卸载实现该方面的共享库。稍后在不相关的地方使用 std::cout 时它会崩溃(真实故事)。因此,您必须完全控制共享库的功能。

此外,dlopen 必须用 RTLD_LOCAL 调用,这样就没有其他东西可以(意外地)使用正在加载的共享库的符号并阻止它卸载。如果你做这样的壮举,你必须阅读并理解 man dlopen