3

在我的场景中,我想要一个插件,它是在运行时加载的共享对象,以访问来自“主机应用程序”的符号,以便我可以向我的应用程序添加任何功能。

我已经尝试过但没有找到任何方法来做到这一点,我不知道这是否可能。那么,我可以以某种方式做到这一点,还是有任何使用插件的应用程序使用的替代方法?

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

4

1 回答 1

3

主要有以下三种方法:

  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 上并不等同于此。
于 2011-10-09T22:26:53.610 回答