Shared Library: undefined reference to `Plugin_API::getName() const'
-
wrote on 23 Jul 2020, 18:35 last edited by fem_dev
I'm developing a Qt C++
shared library
and unintentionally I changed my source-code in a way that not only the plugin interface definition (*.h
) must be in themain app
side, 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 app
side, 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_API
class have:
a) Some pure virtual methods (that will be called by theMain App
- API)
b) Another pure virtual methods (Only to force theMyLib
class 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_H
This header file was copied and pasted inside the
Main App
, and include it in the project. All ok!I have the
plugin_api.cpp
that implements theb)
andc)
cases above. Example:const QString Plugin_API::getName(void) const { return _pluginName; }
Finally, in the
Main App
project 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.cpp
inside theMain App
project.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.h
I declared the_pluginsMapMap
as private member of theApp
class: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.
wrote on 23 Jul 2020, 20:03 last edited by@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!
1/5