Qt App, loading a Qt Dll, crashes on exit



  • Hello,

    I've developped a Qt application that loads a Qt Dll.
    I'm working with Visual Studio 2008 (on Windows XP Pro) and Qt 4.4.3.

    main function :
    @
    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    QtAppClient w;
    w.show();
    return a.exec();
    }
    @

    The client loads the Qt Dll and invokes an exported function "Test_01":
    @
    if(!m_hInstance)
    m_hInstance = LoadLibrary(TEXT("DlgHttpLib.dll"));

    if(m_hInstance){
    if(!m_pfnTest_01)
    m_pfnTest_01 = (pfn)GetProcAddress(m_hInstance, "Test_01");
    }
    else
    m_pfnTest_01 = 0;

    if(m_pfnTest_01){
    (*m_pfnTest_01)();
    }
    @

    with typedef :
    @
    typedef void (*pfn) (void);
    @

    and data members:
    @
    HINSTANCE m_hInstance;
    pfn m_pfnTest_01;
    @

    On library side, the exported function Test_01 :
    @
    extern "C" DLGHTTPLIB_EXPORT void Test_01(void)
    {
    int argc=0;
    QApplication *pApp=0;

    if(!qApp)
    pApp = new QApplication(argc, 0);

    CWFA_HTTP_QT client("myhost.fr", "path_on_server/");

    client.bAddParam("item1", "val1");
    client.bAddParam("item2", "val2");

    bool bRetRequete = false, bHttpS = false, bPost=true;
    long lTimeout = 30000; //ms

    client.bExecute("testconnexion.php", bRetRequete, bHttpS?"O":"N", bPost, lTimeout);

    if (pApp){
    pApp->quit();
    delete pApp;
    }
    @

    Implementation of method "bExecute" (CWFA_HTTP_QT object):
    @
    bool CWFA_HTTP_QT::bExecute(const QString &Function, bool &bRetRequete, const QString &Https, bool bPost, long lTimeout)
    {
    bool bHttps=true;
    if (Https=="N")
    bHttps = false;

    m_bExecuteAEteLance = false;
    m_bRetHttp_requete = false;
    m_bRetRequete = false;

    QUrl url;
    url.setScheme(bHttps? "https" : "http");
    url.setHost(m_Serveur);
    url.setPath(m_CheminServeur+Function);

    QListIterator<QPair<QString,QString>> itQueryItems(m_QueryItems);

    if(bPost){
    // POST
    m_POST_DataBuffer.clear();

    while(itQueryItems.hasNext()){
    QPair<QString, QString> item = itQueryItems.next();

    if(!m_POST_DataBuffer.isEmpty())
    m_POST_DataBuffer.append("&");

    m_POST_DataBuffer.append(item.first + "=" + item.second);
    }
    }
    else{
    // GET
    while(itQueryItems.hasNext()){
    QPair<QString, QString> item = itQueryItems.next();
    url.addQueryItem(item.first, item.second);
    }
    }

    QNetworkAccessManager *pMmanager = new QNetworkAccessManager(this);

    connect(pMmanager, SIGNAL(finished(QNetworkReply *)), this, SLOT(onRequestFinished(QNetworkReply *)));

    // erreur SSL
    connect(pMmanager, SIGNAL(sslErrors(QNetworkReply *, QList<QSslError>)), this, SLOT(onSslErrors(QNetworkReply *, QList<QSslError>)));

    url.setUrl(url.toEncoded());
    QNetworkRequest httpReq(url);

    m_DerniereErreur = 0;
    m_MsgErreurSsl = "";
    m_bRequestFinished = false;

    QNetworkReply *pReply=0;
    if(bPost){
    // POST
    pReply = pMmanager->post(httpReq, m_POST_DataBuffer);
    }
    else{
    // GET
    pReply = pMmanager->get(httpReq);
    }

    connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));

    //m_Loop.exec();

    while(!m_bRequestFinished){
    qApp->processEvents();
    }

    delete pMmanager;
    pMmanager=0;

    m_bExecuteAEteLance = true;
    m_bRetHttp_requete = m_DerniereErreur==0;

    if (m_bRetHttp_requete){
    m_bRetRequete = m_ReplyBuffer.startsWith(ENTETE_OK_HTTP);
    }

    bRetRequete = m_bRetRequete;

    return m_bRetHttp_requete;
    }
    @

    Implementation of SLOT void CWFA_HTTP_QT::onRequestFinished(QNetworkReply *pReply):
    @
    void CWFA_HTTP_QT::onRequestFinished(QNetworkReply *pReply)
    {
    if(pReply && pReply->isReadable()){
    m_ReplyBuffer = pReply->readAll();
    }

    // on débloque le traitement
    //m_Loop.exit();

    m_bRequestFinished = true;

    pReply->close();
    pReply->deleteLater();
    }
    @

    The call is performed normally and gives intended results.
    But the application crashes on exit with this error 0xC0000005 (Access Violation) and gives a break point on "(list->takeFirst())();" in :
    @
    void Q_CORE_EXPORT qt_call_post_routines()
    {
    QVFuncList *list = postRList();
    if (!list)
    return;
    while (!list->isEmpty())
    (list->takeFirst())();
    }
    @

    Thanks in advance for your help.

    Jean



  • I'm not sure, but is it supposed to be only one QApplication instance(global singleton etc...) in Qt?
    Then this code:
    @
    if (pApp){

    pApp->quit();

    delete pApp;
    @

    should break your qApp instance in caller thread...


  • Moderators

    Yes, QApplication is a singleton.



  • That's right !
    These instructions are just added considering the application calling my Qt Dll are not "Qt native" and there is no QApplication instance yet.
    In the present usage qApp is not NULL (instance on app side) and anyway the following instructions won't be executed on Dll side :
    @
    if (pApp){
    pApp->quit();
    delete pApp;
    }
    @


Log in to reply
 

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