我花了几天时间阅读和重新阅读我在该主题上找到的每个教程,并花了几个小时(甚至几天)在 SO 上浏览相关问题,但我仍然无法让以下工作。如果这是重复的,请接受我的道歉:很可能我已经多次看到并重新阅读了重复的问题,但无法理解答案与我的问题的相关性。有了这个...
我正在尝试为我的应用程序实现插件架构。插件作为库编译和安装。在运行时,应用程序然后使用 dlopen() / dlsym() 加载并链接到插件的功能。
这个想法是插件(库)将实现一组函数以将数据返回到主应用程序,或操作从应用程序传递的数据。
为了测试这个想法,我尝试实现一个函数(在插件内部),它将返回插件本身的(人类可读的)名称(作为 std::string)。我认为这将是一件简单的事情开始...... :-/
这是我到目前为止得到的:
// Plugin.cpp
extern "C" void plugin_name(std::string *name) {
name = new std::string("Example plugin name");
}
// Application.cpp
void* handle = dlopen("libplugin.so", RTLD_LAZY);
typedef void (*plugin_t)(std::string*);
dlerror(); // Reset errors.
plugin_t call_plugin_name = (plugin_t) dlsym(handle, "plugin_name");
// ... Some error handling code.
std::string my_plugin_name;
call_plugin_name(&my_plugin_name);
dlclose(handle);
// More code that displays my_plugin_name.
我尝试了许多不同的组合,包括一种看起来更直接(但效果不佳)的组合,其中返回了插件名称:
// Plugin.cpp
extern "C" std::string plugin_name(void) {
return std::string("Example plugin name");
}
我知道我很接近:代码编译并且应用程序停止崩溃;)
但是,我有一个空白空间,我希望看到实际的插件名称。
到目前为止,我阅读的所有教程都非常快速地介绍了双向传递数据的机制:plugin <=> Application. 我正在尝试使用“简单”std::string 做什么,我希望稍后使用更复杂的对象(即插件函数将通过引用获取对象并更改其某些属性)。教程或多或少都停留在使用 dlsym() 创建指针的地方,并且没有提供太多关于如何使用该指针的示例。
那么,如何做到这一切呢?
另一个相关的问题:我是否使用了一个通用的标头,我将同时与应用程序和插件一起使用,以及在哪里定义函数调用签名?我将如何做到这一点,这将如何帮助?