Strange behaviour with function calls in a method



  • Hi there,

    I am fairly new to Qt and C++ programming. I want to use the QXMPP Library to connect to a jabber server. This doesn't seem to work for strange reasons. After many hours of testing, I was able to break it down to this:

    This actually works (its basically the code from the example):

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

    QXmppLogger::getLogger()->setLoggingType(QXmppLogger::StdoutLogging);
    QXmppClient client;
    client.connectToServer("qxmpp.test1ATgmail.com", "qxmpp123");
    

    ...
    @

    while this does not:
    @void foo() {
    QXmppLogger::getLogger()->setLoggingType(QXmppLogger::StdoutLogging);
    QXmppClient client;
    client.connectToServer("qxmpp.test1ATgmail.com", "qxmpp123");
    }

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

    foo();
    

    ...@

    And that doesn't make any sense for me :(

    The first code prints the following to the stdout:
    @Mo. Feb 7 23:36:26 2011 DEBUG Looking up server for domain gmail.com@

    And the second one prints much much more.

    Thanks in advance.



  • For me it is just the other way round. It works with the client directly in the main function, but does not work if I call the foo method (assuming app.exec() after the client code/foo() call).

    That's perfectly ok, you were fooled by C++'s stack allocation :-)

    connectToServer does not block but returns immediately, method foo ends, client goes out of scope and is deleted and there is no more object left to do some work...

    In the working example the client object lives as long as app.exec() has not returned.



  • I understand. I already thought that an object, that is create before app.exec(), might somehow be destroyed.

    What is the "right" way to do this? I think putting everything in the main method wouldn't be that good ;-) I already made a class, because I later have to receive messages too, but the problem here is the same.



  • Where to put things is a matter of your application design. If you want to use signal/slot connections you must create at least a QObject subclass. The rest is up to you - you can put everything into one single class, although nobody will recommend you to do this :-)

    You are new to programming/C++ too?



  • New to C++. I am already experienced in delphi/freepascal and java, but c++ seems to have more pitfalls than those. ;-)

    I aldready made a very simple class, because later I also want to be able to receive messages.
    @#ifndef JABBERCONNECTION_H
    #define JABBERCONNECTION_H

    #include "QXmppClient.h"

    class JabberConnection : public QXmppClient
    {
    public:
    JabberConnection(QString jid, QString password);
    void sendMessage(QString receiver, QString message);
    };

    #endif // JABBERCONNECTION_H@
    @#include "jabberconnection.h"
    #include "QXmppMessage.h"

    JabberConnection::JabberConnection(QString jid, QString password) {
    QXmppLogger::getLogger()->setLoggingType(QXmppLogger::StdoutLogging);
    connectToServer(jid, password);
    }

    void JabberConnection::sendMessage(QString receiver, QString message) {
    sendPacket(QXmppMessage("",receiver, message));
    }
    @
    Using this class makes no difference. I also use sendMessage() in an inifinite loop (with some conditions of course), which should prevent the deletion of that instance, but it doesn't.
    It looks a bit like this at the moment:

    @void foo() {
    JabberConnection client("qxmpp.test1ATgmail.com", "qxmpp123");

    while (true) {
       if (condition) {
          client.sendPacket(...);
       }
    }
    

    }
    ...@

    EDIT: I think found the cause of the problem. Because of the infinite loop, app.exec() is never executed. But I don't know another way. Or does Qt have a special way to use infinite loops? Normally I would use a seperate thread, but I don't know how these work in Qt/C++.



  • The Qt way to do things, is to create the QObject based objects on the heap and use pointers. The rest is done using connecting signals to slots or calling slots directly.

    I'd suggest you make yourself comfortable with the principles of C++ and Qt first. And don't do it with a Jabber client, this project is much too complicated for a learning project. Please don't get me wrong, I don't want to offend you, but I have the strong feeling, that you need some basics first. There are some good tutorials for C++ out there and Qt tutorials on http://doc.qt.nokia.com and in the DevNet wiki.

    In particular, you should get away from Delphi's and Java's object models. They are not applicable in C++ and Qt. The tutorials will teach you the difference between creating objects on the stack and on the heap and when to use either one.

    Once you feel comfortable with the concepts and the way how the Qt objects interact with each other, you will have much more fun with creating your Jabber client :-) And of course you're welcome to ask your questions here.



  • Thank your for your advice. I think I now understand the SIGNAL-SLOT concept, because with excessive use of those (and a QTimer ^^) it finally works. Thanks a lot.



  • ""New to C++. I am already experienced in delphi/freepascal and java, but c++ seems to have more pitfalls than those""

    I work on a company with a background on Delphi programming and I'm trying to introduce them C++ and Qt (plus COM programming).

    The answer for that Pfaeff is pretty straight forward.. C++ allows Stack Allocation of objects... for, as far as I know, Delphi doesn't.. objects on delphi are are always allocated on the heap using .Create...

    What Volker said is true. I also recommend the book Thinking in C++ , from Bruce Eckel.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.