0

I've been trying to get Qt DBus working, but no luck. It seems that my application isn't receiving the signals that it should. I've monitored DBus using dbus-monitor --system and it shows that the signals are indeed being generated. When I make a method DBus method call with Qt, the response comes back just fine. Even when running with QDBUS_DEBUG=1, nothing is printed showing that Qt received the signals. Am I missing something obvious?

Here's the code that should work, but doesn't (nothing prints to the console):

class Example1 : public QObject
{
    Q_OBJECT
public:
    Example1(QObject* parent = NULL) : QObject(parent)
    {
    }
    void setupDBus()
    {
        // Get the system bus
        QDBusConnection dBusSystem = QDBusConnection::systemBus();
        // check if it is connected
        if (!dBusSystem.isConnected())
        {
            qFatal("Cannot connect to the D-Bus session bus.");
            return;
        }
        // register "device added"
        Q_ASSERT(dBusSystem.connect("org.freedesktop.UDisks",
                                "/org/freedesktop/UDisks",
                                "org.freedesktop.UDisks",
                                "DeviceAdded",
                                this,
                                SLOT(deviceAdded(const QDBusObjectPath&))));
        // register "device removed"
        Q_ASSERT(dBusSystem.connect("org.freedesktop.UDisks",
                                "/org/freedesktop/UDisks",
                                "org.freedesktop.UDisks",
                                "DeviceRemoved",
                                this,
                                SLOT(deviceRemoved(const QDBusObjectPath&))));
    }
private slots:
    // slot for "device added"
    void deviceAdded(const QDBusObjectPath &in)
    {
        qDebug() << "device added: "; //<< in.path();
    }
    // slot for "device removed"
    void deviceRemoved(const QDBusObjectPath &in)
    {
        qDebug() << "device removed: "; //<< in.path();
    }
};


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Example1 example;
    example.setupDBus();

    return a.exec();
}
Eric D
  • 141
  • 2
  • 9
  • putting the connect into assert() is a bad idea, because it won't be executed at all then in release mode/when assertions are disabled. – Frank Osterfeld Jan 15 '16 at 06:13
  • @FrankOsterfeld I didn't know that! I was just blindly copying a tutorial and assumed that Q_ASSERT always ran. As it turns out, I was running my program in Release mode due to other reasons, so this was the culprit. If you expand your comment into a formal answer, I'd be happy to accept it. – Eric D Jan 16 '16 at 04:03

1 Answers1

1

The problem here is that code in Q_ASSERT() (or assert()) isn't run when the code is built in release mode. That means your connect() calls are never executed in release mode.

Thus side-effects inside Q_ASSERT()/assert() are a bad idea and should be avoided, to ensure the code does the same independent of debug vs. release mode. (also one of the first things to check if something works in debug mode but not in release mode).

Frank Osterfeld
  • 24,815
  • 5
  • 58
  • 70