Shared Library: undefined reference to `Plugin_API::getName() const'
-
I'm developing a Qt C++
shared libraryand unintentionally I changed my source-code in a way that not only the plugin interface definition (*.h) must be in themain appside, but the implementation too.I know that is wrong, but I can't found how to fix it.
If I remove the implementation on themain appside, I got this compilation time error:undefined reference to `Plugin_API::getName() const'The code is very long, but I will try to resume here:
My
Plugin_APIclass have:
a) Some pure virtual methods (that will be called by theMain App- API)
b) Another pure virtual methods (Only to force theMyLibclass to implement them. They are not called direct by theMain App)
c) Private, protected and public methods
d) Some signals (that will be used for all developed plugins)#ifndef PLUGIN_QT_API_H #define PLUGIN_QT_API_H #include <QtPlugin> #include <QString> class Plugin_API : public QObject { Q_OBJECT private: ... protected: ... public: Plugin_API(); virtual ~Plugin_API() = default; ... const QString getName(void) const; public slots: ... signals: ... }; Q_DECLARE_INTERFACE(Plugin_API, "com.rotortest.plugin") #endif // PLUGIN_QT_API_HThis header file was copied and pasted inside the
Main App, and include it in the project. All ok!I have the
plugin_api.cppthat implements theb)andc)cases above. Example:const QString Plugin_API::getName(void) const { return _pluginName; }Finally, in the
Main Appproject I included#include "plugin_api.h".
I loaded it using QPluginLoader. It works!
So, I'm trying to use the loaded plugin in this way:void App::SomeMethod() { const QString pluginName = plugin->getName(); }But I got this compile time error:
undefined reference to `Plugin_API::getName() const'The only way that I found to solve this is copying and pasting the
plugin_api.cppinside theMain Appproject.Could you help me?
UPDATE 1
Here is how I loaded all plugins inside the
Main App:void App::loadPlugins(const QStringList pluginsList) { foreach(QString file, pluginsList) { QPluginLoader loader(file); // Error checking: if (!loader.load()) { sendErrorMsg(tr("%1: ").arg(loader.errorString())); continue; } // Get and display the plugin file name: const QStringList pathSplited = loader.fileName().split("/"); const QString fileName = pathSplited.last(); sendStatusMsg(tr("Loading plugin: %1").arg(fileName)); // Cast plugin interface: Plugin_API* plugin = qobject_cast<Plugin_API*>(loader.instance()); // Error chekcing: nullptr if (!plugin) { sendErrorMsg(tr("Wrong Plugin API! Could not cast: %1").arg(loader.fileName())); continue; } // ===== CONNECT ALL SIGNALS / SLOTS ===== // bool conn1 = connect(plugin, &Plugin_API::sendMsg, this, &App::receivedMsg); bool conn2 = connect(plugin, &Plugin_API::savePluginSettings, this, &App::receivedPluginSettings); bool allConnections = conn1 & conn2; if (!allConnections) { sendErrorMsg(tr("Unable to connect: %1").arg(plugin->getName())); continue; } plugin->setProject(&_project); // Store the plugin in a map: _pluginsMapMap[plugin->getType()][plugin->getName()] = plugin; } }In the
app.hI declared the_pluginsMapMapas private member of theAppclass:std::map<QString, std::map<QString, Plugin_API*>> _pluginsMapMap; -
Then you should start with the habit of properly exporting the symbols you want to use otherwise you'll have surprises on Windows.
Your plugin interface is not a pure virtual interface hence your app has to know its implementation.
In this case the proper design is:
- shared library
- plugin
- application
The shared library provides the core class that will be used by both the plugin and the application.
-
Hi,
As already asked on your other thread, are you developing on Windows ?
-
Then you should start with the habit of properly exporting the symbols you want to use otherwise you'll have surprises on Windows.
Your plugin interface is not a pure virtual interface hence your app has to know its implementation.
In this case the proper design is:
- shared library
- plugin
- application
The shared library provides the core class that will be used by both the plugin and the application.
-
Then you should start with the habit of properly exporting the symbols you want to use otherwise you'll have surprises on Windows.
Your plugin interface is not a pure virtual interface hence your app has to know its implementation.
In this case the proper design is:
- shared library
- plugin
- application
The shared library provides the core class that will be used by both the plugin and the application.
@SGaist said in Shared Library: undefined reference to `Plugin_API::getName() const':
Then you should start with the habit of properly exporting the symbols you want to use otherwise you'll have surprises on Windows.
Perfect explanation! Thank you so much!