You are not logged in.

1

Wednesday, October 19th 2011, 2:38pm

Signal/Slots connection does not work with no warning, error or whatsoever!

Hi,
in my application there is a bunch of plugins (all implementing the same interface) that communicate with the "core application" via the signal/slot mechanism. Each plugin has a getComm() method which returns the interface class (comm object) that contains the signals/slots (and the data structures) to enforce communication between the plugin and the core application. The comm class is a private member of the plugin class.

When a plugin needs data from the core application, its Communication Interface object emits a "requestDataFromCoreApp" signal, which is connected to the pluginRequestReceiver slot in the core application.
When a plugin sends data to the core application, its Communication Interface object emits a "readyToSend" signal, which is connected to the pluginRequestReceiver slot in the core application as well (but, in this case, the data is passed as parameter to the slot).

Simplified code of the loader method in the core application:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
QDir pluginsDir = directoryOf("plugins");
foreach (QString fileName, pluginsDir.entryList(QDir::Files)) 
{
        QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
	if (MyPlugin *pluginIFC = qobject_cast<MyPlugin*>(loader.instance())) {
			interfaces.append(pluginIFC);
			int j = getPluginIndexByName(pluginIFC->name());
			if (j!=-1) {
				myPluginsInterfaces[j] = pluginIFC->getPluginComm();
				
				connect(myPluginsInterfaces[j],	SIGNAL(readyToSend(PluginType,GenericDataExchange*)),
						this(),					SLOT(pluginRequestReceiver(PluginType,GenericDataExchange*)));

				connect(myPluginsInterfaces[j],	SIGNAL(requestDataFromCoreApp(PluginType)),
						this(),					SLOT(pluginRequestReceiver(PluginType)));

			}
		}

NOTES:
  • the getPluginIndexByName function simply returns an int with the index assigned to that plugin.
  • the interfaces object is declared as QList <MyPlugin*> interfaces;
  • myPluginsInterfaces is declared as PluginCoreCommunicationInterface* myPluginsInterfaces[max_number_of_plugins];


In reply to a plugin's request, the core application will send the data by using the pluginComm.sendDataToPlugin(data) method which makes the plugin comm object emit a dataReceived() signal.
In each plugin's constructor the dataReceived() signal of the pluginComm class is connected to an appropriate slot in the plugin class (getDataFromCoreApp).

Simplified code of each plugin's constructor:

Source code

1
connect(this->pluginComm,SIGNAL(dataReceived()),this,SLOT(getDataFromCoreApp()));


This architecture WORKS. It simply works, EXCEPT for one particular plugin and I can't figure out why. I've checked everything I could think of: the signals are declared as such, and so are the slots; the signals are actually emitted; the code where the signal is fired is actually reached; the signal/slot connection doesn't make any warning appear in debug mode; the plugin that doesn't work has the same base structure as the others; it has the Q_OBJECT macro in the header file; it is recognized as a plugin, so it is loaded. It's just that the signal/slot mechanism doesn't work in that plugin: I don't get any error, nor warning. I've also tried to connect a test_signal() signal to a test_slot() slot within the same plugin, and to forcibly have it fired in the plugin's constructor but the slot is never reached.

Since I don't get any clue from the debugger on what the heck is going wrong, it's very difficult for me to figure it out. Maybe someone has had the same issue before, I've searched on google for an answer but no luck so far. Any ideas?

Thanks in advance for your help!

This post has been edited 1 times, last edit by "budiulik" (Oct 19th 2011, 3:09pm)


Junior

Professional

  • "Junior" is male

Posts: 1,623

Location: San Antonio, TX USA

Occupation: Senior Secure Systems Engineer

  • Send private message

2

Wednesday, October 19th 2011, 2:55pm

There might be something with QMetaType not understanding PluginType and GenericDataExchange*.
Did you register these as QMetaType's with qRegisterMetaType? Though I would of think the compiler would of complained during compiling (then again I've seen it where it hasn't too based on -O level setting).

If they are just from know types then maybe just using something like readyToSend( int, const char* ) would work.

Just a thought...

3

Wednesday, October 19th 2011, 3:22pm

hi Junior, thanks for you reply. The signal/slots works for 6 plugins out of 7. So the PluginType and GenericDataExchange types are recognized correctly.

Maybe I've put you on the wrong track describing the whole architecture:
I've tried to create a couple of signal/slot inside the plugin that doesn't work: a QTimer whose timeout() signal I associate to a mainLoop() slot within my class. The slot is not reached. It seems to be a problem with the Plugin class but I can't figure out what it is.

Plugin.h

Source code

1
2
3
4
5
6
7
8
9
10
11
12
class Plugin: public QWidget, public MyPlugin
{	
	Q_OBJECT
	Q_INTERFACES(MyPlugin)
public:
	Plugin(QWidget *parent = 0, Qt::WFlags flags = 0);
	~Plugin();
private:
       QTimer* mainTimer;
private slots:
	void mainLoop();
};



Plugin.cpp

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "Plugin.h"

Plugin::Plugin(QWidget *parent, Qt::WFlags flags)
	: QWidget(parent, flags)
{	
       	mainTimer = new QTimer(this);
	r= connect(mainTimer, SIGNAL(timeout()), this, SLOT(mainLoop()));   
	if (!r)
		Q_ASSERT(r);
       mainTimer->start(1000);
}

void Plugin::mainLoop() 
{
    // do something - but this code is never reached
}

Q_EXPORT_PLUGIN2(Plugin, Plugin);

This post has been edited 2 times, last edit by "budiulik" (Oct 19th 2011, 3:48pm)


Junior

Professional

  • "Junior" is male

Posts: 1,623

Location: San Antonio, TX USA

Occupation: Senior Secure Systems Engineer

  • Send private message

4

Wednesday, October 19th 2011, 3:32pm

From the code posted, you have the connect going to a local slot (this), but the slot mainLoop() is not defined in the class as a slot.

ah - got the update..

5

Wednesday, October 19th 2011, 3:34pm

my mistake. in the actual code mainLoop is defined as a private slot, but in the simplified code that I reported here I forgot to include its declaration :)

I edited my previous post with the corrected code.

Also, I didn't mention that I'm using QT 4.2.3 with Visual Studio 2005.

Junior

Professional

  • "Junior" is male

Posts: 1,623

Location: San Antonio, TX USA

Occupation: Senior Secure Systems Engineer

  • Send private message

6

Wednesday, October 19th 2011, 3:46pm

I see nothing wrong here that is posted. Scope is good, declaration are good, no conflict of naming that I can see.
Maybe try direct include of classes QTimer, QObject. // odd if this works //

Check to ensure that a moc file was created for this as well. Maybe the Makefile did not get updated after adding the Q_OBJECT macro. (qmake)

// some thoughts

7

Wednesday, October 19th 2011, 3:53pm

The moc file is generated correctly. I compared it to the moc file generated from a plugin that works, and they are practically identical to my eyes. I've also tried to remove the Q_OBJECT macro, build the project, put the Q_OBJECT macro back and build everything again to make sure that the moc file is re-generated correctly.

All the connect methods return TRUE. Have you ever experienced such a situation? I think I will go through the process of creating a new project from scratch and see if it works, because I'm afraid that something buried deeply somewhere in the QT-Visual Studio add-in is preventing this class to behave as expected.

Junior

Professional

  • "Junior" is male

Posts: 1,623

Location: San Antonio, TX USA

Occupation: Senior Secure Systems Engineer

  • Send private message

8

Wednesday, October 19th 2011, 4:07pm

Maybe just build that plugin as a standalone for testing and rule it out. Though from what you posted it should work. It's like the plugin isn't creating an eventloop for itself thus causing the timer not to fire. Might try also creating a global app eventFilter and then use installEventFilter on that plugin right after instantiation just to see if any events are being fired from the plugin itself. This might provide some useful feedback.

9

Wednesday, October 19th 2011, 7:41pm

test the plugin in isolation. Do not post 'simplified' code because it never helps. If your code is too complicate, make a simple example that shows the same bug.

posting something that is complete, concise and compilable will help no-end.

Why nobody ever does this in the first place...
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

10

Thursday, October 20th 2011, 8:36am

Because this particular situation was not replicable. I have several plugins, all with the same structure, and they all work except this particular one. The code I posted was meant to give an idea of the situation and was not supposed to be self-contained and compilable. I was just trying to describe the situation and asking if somebody has had the same issue, which is clearly (in my opinion) a bug in the MOC or in the QT Visual Studio add-in.

Anyway: I created a new project from scratch and copied all the code in there. Everything works fine, with the same code. Don't have a clue what the hell happened with that plugin.

Thanks anyway for your answers. ;)

11

Thursday, October 20th 2011, 12:56pm

the plugin builds up the post build events so that moc etc is run. The only thing the plugin can do wrong is pass in some wrong parameters. From memory, the only parameters it passes are include paths and source code files (and some pre processor directives). If the plugin went wrong there would no doubt be a tool (moc) or compiler error.

I have experienced the plugin not working, but in that case it was very obvious - I got linker errors because the plugin failed to make the build events at all.
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

12

Wednesday, January 11th 2012, 9:16am

I figured out what the problem was after a while. The issue was caused because the plugin that wasn't working was using (by mistake) debug versions of Qt Libraries in release mode. That caused the problem, without any warning or error message.
I hope this can possibly help somebody with the same issue.

13

Wednesday, January 11th 2012, 12:37pm

ahh, so you were hiding information!! it presumably works fine in debug mode, and you only have a problem in release? ...
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

14

Wednesday, January 11th 2012, 1:00pm

Yes, I confess. :)

15

Wednesday, January 11th 2012, 10:46pm

tbh, I'm surprised that that is the only thing that went wrong when linking with the wrong library
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

Similar threads