从动态加载的库(QPluginLoader)调用主程序函数

Calling main program functions from a dynamically loaded library (QPluginLoader)

本文关键字:调用 主程序 函数 QPluginLoader 动态 加载      更新时间:2023-10-16

我在运行时使用Qt QPluginLoader类动态加载插件(dll)。

到目前为止,我已经成功地加载了从主程序调用函数的插件。现在,插件需要调用主程序中的其他函数。我已经在插件项目中包含了相关的头文件,并且它的编译没有错误。

当我试图从主程序调用以下插件函数时:

// main program calling a function in a dll that has been dynamically
// loaded into the program:
PluginInterface* plugin = qobject_cast<PluginInterface*>(QPluginLoader(path)).instance();
plugin->DoSomething(); // works, writes a message to the console
plugin->callMainProgramFunction(); // not working

// test method in the plugin project (dll) that writes to console:
void TestDLL::DoSomething();
{
   std::cout << "Hello, this messages comes from TestDLL! Have a nice day"; // works
}

// test method in the plugin project (dll) that tries to 
// call a method in the main program: 
void TestDLL::callMainProgramFunction()
{  
    Angle test; // angle.h is included, and offers geometric functions
    std::cout << test.sine() << "n"; // does not work, program stops
}

程序停止。我相信这是因为插件不知道在哪里找到符号(从angle.cpp链接并编译到主程序中的代码),因为它随后被动态链接到程序中。

许多插件将使用相同的函数,因此我认为编译每个插件的所有实现是一个坏主意。

是否有解决方案,使用QPluginLoader?我怎么能告诉动态加载的插件在哪里找到主程序中的符号?我知道QLibrary提供了一种更手动的方式来导出/导入函数和"解析符号",但缺乏QPluginLoader的简洁实例功能。

您可以创建一个包含插件和主程序之间共享的公共函数的dll,并将其链接到主程序和插件中。

QPluginLoader解决了我所描述的问题:通过QPluginLoader动态加载到主程序中的库将能够调用主程序中的函数。

我的问题的原因是一个微妙的错误在我使用的插件界面。

这是可能的,但不要忘记在Linux上将主程序与-rdynamic标志链接起来,以便从插件中可以看到主程序的符号。