在我的场景中,我想要一个插件,它是在运行时加载的共享对象,以访问来自“主机应用程序”的符号,以便我可以向我的应用程序添加任何功能。
我已经尝试过但没有找到任何方法来做到这一点,我不知道这是否可能。那么,我可以以某种方式做到这一点,还是有任何使用插件的应用程序使用的替代方法?
我在 Fedora 15、Linux 2.6.4 上。但是,我希望解决方案是跨平台的。
在我的场景中,我想要一个插件,它是在运行时加载的共享对象,以访问来自“主机应用程序”的符号,以便我可以向我的应用程序添加任何功能。
我已经尝试过但没有找到任何方法来做到这一点,我不知道这是否可能。那么,我可以以某种方式做到这一点,还是有任何使用插件的应用程序使用的替代方法?
我在 Fedora 15、Linux 2.6.4 上。但是,我希望解决方案是跨平台的。
主要有以下三种方法:
将函数指针结构从应用程序传递给 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();
}
将您的应用程序移动到一个库中,并让可执行文件简单地链接到该库中并在其中调用一个入口点。然后您的插件可以链接相同的库并轻松访问其符号。这也是相当可移植的,但由于需要在主应用程序库中使用与位置无关的代码,可能会导致一些性能损失(尽管在这种情况下您可能能够摆脱固定映射,具体取决于您的架构) .
-rdynamic
直接从应用程序可执行文件中导出符号。但是,这对于其他平台不是很便携 - 特别是,这些在 Windows 上并不等同于此。