我可以从运行时加载的共享对象访问主机进程的符号吗?还有其他选择吗?

发布于 2024-12-08 17:00:28 字数 207 浏览 0 评论 0原文

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

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

我使用的是 Fedora 15、Linux 2.6.4。不过,我希望解决方案是跨平台的。

In my scenario I want a plugin, which is a shared object loaded in runtime, to access symbols from the “host application” so I can add any functionality to my application.

I have tried but have not found any way to do this and I have no clue on whether this is possible or not. So, can I do this somehow or is there any alternative that applications that use plugins use?

I am on Fedora 15, Linux 2.6.4. However, I hope the solution will be cross-platform.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

葬花如无物 2024-12-15 17:00:29

主要有以下三种方法:

  1. 将函数指针结构从应用程序传递到 DLL,从而可以访问您想要共享的任何符号。这是最可移植的方法,但创建所有函数指针有点痛苦。类似于:

    // 在共享标头中
    结构体app_vtable {
      无效(*appFoo)();
    };
    
    // 在插件中:
    const app_vtable *vt;
    void set_vtable(const app_vtable *vt_) {
      vt = vt_;
    }
    
    无效栏(){
      vt->appFoo();
    }
    
    // 在应用中:
    无效 foo();
    const app_vtable vt = { foo };
    
    无效负载插件(){
      void *plugin = dlopen("plugin.so", RTLD_LAZY);
      void (*pset_vtable)(const app_vtable *) = dlsym(插件, "set_vtable");
    
      pset_vtable(&vt);
    
      void (*pbar)() = dlsym(插件, "酒吧");
      pbar();
    }
    
  2. 将您的应用程序移至库中,然后让可执行文件简单地链接到该库中并调用其中的入口点。然后您的插件可以链接同一个库并轻松访问其符号。这也相当可移植,但由于需要在主应用程序库中使用与位置无关的代码,可能会导致一些性能损失(尽管在这种情况下,您可能能够摆脱固定映射,具体取决于您的架构) .

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

There are three main approaches:

  1. Pass a structure of function pointers to the DLL from the application, giving access to whatever symbols you want to share. This is the most portable method, but is kind of a pain to create all the function pointers. Something like:

    // 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. Move your application into a library, and have the executable simply link in this library and call an entry point in it. Then your plugins can link the same library and access its symbols easily. This is also quite portable, but can result in some performance loss due to the need to use position-independent code in your main app library (although you may be able to get away with a fixed mapping in this case, depending on your architecture).

  3. On Linux only (and possible other ELF platforms) you can use -rdynamic to export symbols from the application executable directly. However this isn't very portable to other platforms - in particular, these is no equivalent to this on Windows.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文