我可以从运行时加载的共享对象访问宿主进程的符号吗?任何选择

Can I access to symbols of the host process from a shared object loaded in runtime? Any alternative?

本文关键字:进程 符号 选择 任何 宿主 访问 运行时 加载 共享 对象 我可以      更新时间:2023-10-16

在我的场景中,我想要一个插件,这是一个在运行时加载的共享对象,从"主机应用程序"访问符号,所以我可以添加任何功能到我的应用程序

我已经尝试过了,但没有找到任何方法来做到这一点,我不知道这是否可能。那么,我能不能这样做呢?或者,有没有其他方法可以替代使用插件的应用呢?

我是Fedora 15, Linux 2.6.4。但是,我希望解决方案是跨平台的。

主要有三种方法:

  1. 从应用程序向DLL传递函数指针结构,允许访问您想要共享的任何符号。这是最便携的方法,但是创建所有的函数指针有点麻烦。比如:

    // In shared header
    struct app_vtable {
      void (*appFoo)();
    };
    // In plugin:
    const app_vtable *vt;
    void set_vtable(const app_vtable *vt_) {
      vt = vt_;
    }
    void bar() {
      vt->appFoo();
    }
    // In application:
    void foo();
    const app_vtable vt = { foo };
    void loadplugin() {
      void *plugin = dlopen("plugin.so", RTLD_LAZY);
      void (*pset_vtable)(const app_vtable *) = dlsym(plugin, "set_vtable");
      pset_vtable(&vt);
      void (*pbar)() = dlsym(plugin, "bar");
      pbar();
    }
    
  2. 将您的应用程序移动到一个库中,并在该库中简单地链接可执行文件并调用其中的入口点。然后,您的插件可以链接相同的库并轻松访问其符号。这也是相当可移植的,但由于需要在主应用程序库中使用与位置无关的代码,可能会导致一些性能损失(尽管在这种情况下,根据您的体系结构,您可能能够使用固定映射)。

  3. 仅在Linux(以及可能的其他ELF平台)上,您可以使用-rdynamic直接从应用程序可执行文件中导出符号。然而,这不是很可移植到其他平台-特别是,这些在Windows上是不等价的。