Signals Inheritance: undefined symbol
-
wrote on 22 Jul 2020, 17:15 last edited by
I'm developing a C++
shared library
(plugin) to my Qt GUI application.Both: main app and plugin projects compile without any warnings or errors. All ok!
My plugin have 2 classes:
Plugin_API
class (shared library interface)Plugin
class
So
Plugin
inherits all public and protected methods (signals too, right?) fromPlugin_API
:class Plugin : public Plugin_API
Inside
Plugin_API
class I have asignal
calledsendMsg
:Inside of
Plugin_API.h
file:void sendMsg(const QString source, const MSG_TYPE msgType, const QString msg) const;
When I run my main application, it loads the plugin and connects the
signal
with a appslot
with success! No errors!bool conn1 = connect(plugin, &Plugin_API::sendMsg, this, &App::receivedMsg); if (!conn1) { sendErrorMsg(tr("Unable to connect: %1").arg(plugin->getName())); continue; }
After that, my main UI opens and I open the plugin UI.
When I click in the button that emit thesendMsg()
...the main application crashs and gives me a console error at run-timelibLobular-Bearing-Plugin.so: undefined symbol: _ZNK10Plugin_API7sendMsgE7QString8MSG_TYPES0_
Why?
How can I fix it? -
@SGaist I will explain better here...
My goal is: send a signal from my plugin
on_save_btn_clicked()
Dialog event to my Main Application.Here is a simple diagram:
plugin_qt_api.h
:#ifndef PLUGIN_QT_API_H #define PLUGIN_QT_API_H #include <QObject> #include <QString> #include "message_types.h" class Plugin_API : public QObject { private: protected: void sendStatusMsg(const QString& msg) const; public: Plugin_API(); virtual ~Plugin_API() = default; signals: void sendMsg(const QString source, const MSG_TYPE msgType, const QString msg) const; }; // Declare our interface: Q_DECLARE_INTERFACE(Plugin_API, "com.rotortest.plugin") #endif // PLUGIN_QT_API_H
plugin_qt_api.cpp
:#include "plugin_qt_api.h" void Plugin_API::sendStatusMsg(const QString& msg) const { emit sendMsg("Plugin", MSG_TYPE::STATUS_MSG, msg); }
dialog.h
:#ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include "plugin_qt_api.h" namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = nullptr); ~Dialog(); private slots: void on_save_btn_clicked(); private: Ui::Dialog *ui; }; #endif // DIALOG_H
dialog.cpp
#include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); } Dialog::~Dialog() { delete ui; } void Dialog::on_save_btn_clicked() { emit sendStatusMsg("Ui Saved!"); }
So, what I have tried before:
From
Dialog::on_save_btn_clicked()
method, emit a signal to thePlugin Class
....and from thisPlugin
class I was sending the same data again to theMain App
using another signal fromPlugin
toMain App
.So...2 steps to send data from
Dialog
class toMain App
.It compiles Ok...no errors, but gives me the error that I wrote here in the first post above.
Now, my question is a little bit different:
Is there a way to send a signal from theDialog::on_save_btn_clicked()
direct to the Main App?
Obs.: May be I could#include plugin_qt_api.h
in thedialog.h
??How can I do it?
Thanks!
wrote on 23 Jul 2020, 12:51 last edited by KroMignon@fem_dev First I would suggest you to a
Q_OBJECT
to yourPlugin_API
class header:class Plugin_API : public QObject { Q_OBJECT ... };
Then, other point, as @SGaist asked before, if you are running on Windows OS, you have to export the class to made it visible from outside and to be able to got access to this class.
You have to do something like this:
- modify the plugin project to add
DEFINES += MYPLUGIN_LIBRARY
- add export macro declaration in a header file (for example
myplugin_macros.h
)
#include <QtCore/qglobal.h> #if defined(MYPLUGIN_LIBRARY) # define MYPLUGIN_EXPORT Q_DECL_EXPORT #else # define MYPLUGIN_EXPORT Q_DECL_IMPORT #endif
- and modify again the class declaration a follow:
#include "myplugin_macros.h" class MYPLUGIN_EXPORT Plugin_API : public QObject { Q_OBJECT ... };
Hope this could help you
take a look at https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application for more detailled explanation.
- modify the plugin project to add
-
Hi,
Can you show your code ?
How are you separating the plugin and the application ?
-
wrote on 22 Jul 2020, 19:42 last edited by fem_dev
@SGaist I will explain better here...
My goal is: send a signal from my plugin
on_save_btn_clicked()
Dialog event to my Main Application.Here is a simple diagram:
plugin_qt_api.h
:#ifndef PLUGIN_QT_API_H #define PLUGIN_QT_API_H #include <QObject> #include <QString> #include "message_types.h" class Plugin_API : public QObject { private: protected: void sendStatusMsg(const QString& msg) const; public: Plugin_API(); virtual ~Plugin_API() = default; signals: void sendMsg(const QString source, const MSG_TYPE msgType, const QString msg) const; }; // Declare our interface: Q_DECLARE_INTERFACE(Plugin_API, "com.rotortest.plugin") #endif // PLUGIN_QT_API_H
plugin_qt_api.cpp
:#include "plugin_qt_api.h" void Plugin_API::sendStatusMsg(const QString& msg) const { emit sendMsg("Plugin", MSG_TYPE::STATUS_MSG, msg); }
dialog.h
:#ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include "plugin_qt_api.h" namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = nullptr); ~Dialog(); private slots: void on_save_btn_clicked(); private: Ui::Dialog *ui; }; #endif // DIALOG_H
dialog.cpp
#include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); } Dialog::~Dialog() { delete ui; } void Dialog::on_save_btn_clicked() { emit sendStatusMsg("Ui Saved!"); }
So, what I have tried before:
From
Dialog::on_save_btn_clicked()
method, emit a signal to thePlugin Class
....and from thisPlugin
class I was sending the same data again to theMain App
using another signal fromPlugin
toMain App
.So...2 steps to send data from
Dialog
class toMain App
.It compiles Ok...no errors, but gives me the error that I wrote here in the first post above.
Now, my question is a little bit different:
Is there a way to send a signal from theDialog::on_save_btn_clicked()
direct to the Main App?
Obs.: May be I could#include plugin_qt_api.h
in thedialog.h
??How can I do it?
Thanks!
-
Are you on Windows ?
-
@SGaist I will explain better here...
My goal is: send a signal from my plugin
on_save_btn_clicked()
Dialog event to my Main Application.Here is a simple diagram:
plugin_qt_api.h
:#ifndef PLUGIN_QT_API_H #define PLUGIN_QT_API_H #include <QObject> #include <QString> #include "message_types.h" class Plugin_API : public QObject { private: protected: void sendStatusMsg(const QString& msg) const; public: Plugin_API(); virtual ~Plugin_API() = default; signals: void sendMsg(const QString source, const MSG_TYPE msgType, const QString msg) const; }; // Declare our interface: Q_DECLARE_INTERFACE(Plugin_API, "com.rotortest.plugin") #endif // PLUGIN_QT_API_H
plugin_qt_api.cpp
:#include "plugin_qt_api.h" void Plugin_API::sendStatusMsg(const QString& msg) const { emit sendMsg("Plugin", MSG_TYPE::STATUS_MSG, msg); }
dialog.h
:#ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include "plugin_qt_api.h" namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = nullptr); ~Dialog(); private slots: void on_save_btn_clicked(); private: Ui::Dialog *ui; }; #endif // DIALOG_H
dialog.cpp
#include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); } Dialog::~Dialog() { delete ui; } void Dialog::on_save_btn_clicked() { emit sendStatusMsg("Ui Saved!"); }
So, what I have tried before:
From
Dialog::on_save_btn_clicked()
method, emit a signal to thePlugin Class
....and from thisPlugin
class I was sending the same data again to theMain App
using another signal fromPlugin
toMain App
.So...2 steps to send data from
Dialog
class toMain App
.It compiles Ok...no errors, but gives me the error that I wrote here in the first post above.
Now, my question is a little bit different:
Is there a way to send a signal from theDialog::on_save_btn_clicked()
direct to the Main App?
Obs.: May be I could#include plugin_qt_api.h
in thedialog.h
??How can I do it?
Thanks!
wrote on 23 Jul 2020, 12:51 last edited by KroMignon@fem_dev First I would suggest you to a
Q_OBJECT
to yourPlugin_API
class header:class Plugin_API : public QObject { Q_OBJECT ... };
Then, other point, as @SGaist asked before, if you are running on Windows OS, you have to export the class to made it visible from outside and to be able to got access to this class.
You have to do something like this:
- modify the plugin project to add
DEFINES += MYPLUGIN_LIBRARY
- add export macro declaration in a header file (for example
myplugin_macros.h
)
#include <QtCore/qglobal.h> #if defined(MYPLUGIN_LIBRARY) # define MYPLUGIN_EXPORT Q_DECL_EXPORT #else # define MYPLUGIN_EXPORT Q_DECL_IMPORT #endif
- and modify again the class declaration a follow:
#include "myplugin_macros.h" class MYPLUGIN_EXPORT Plugin_API : public QObject { Q_OBJECT ... };
Hope this could help you
take a look at https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application for more detailled explanation.
- modify the plugin project to add
-
wrote on 23 Jul 2020, 13:37 last edited by
@SGaist said in Signals Inheritance: undefined symbol:
Are you on Windows ?
No. I'm in Linux Ubuntu 20.04, but I will compile my
Main App
and my developedplugins
in another OS: Windows 10 and Mac OSX.@KroMignon said in Signals Inheritance: undefined symbol:
You have to do something like this:
Thank you, I will do that!!
Thank you guys!
1/6