QNetworkAccessManager friert ein (bei Aufruf aus dll)

Alles rund um die Programmierung mit Qt
Antworten
bobcat
Beiträge: 125
Registriert: 21. April 2010 14:51

QNetworkAccessManager friert ein (bei Aufruf aus dll)

Beitrag von bobcat »

Ich mache folgenden einfachen Aufruf:

Code: Alles auswählen

QNetworkAccessManager manager;
QNetworkReply* reply;
reply = manager.get(*request);
Meinen Code kompiliere ich in eine exe, führe diese aus und aus der exe wird der get-Request auch wie erwartet ausgeführt.

Ich verwende den Code allerdings auch noch in einem anderen Umfeld:
Ich habe eine Python-Anwendung, aus der ich über die Python-Bindings von PyQt auf Qt zugreife. Meinen obigen Code (der auch das QMainWindow enthält) habe ich in eine dll kompiliert und auch Python-Bindings erstellt. Ich starte also in meinem Python Skript meine QApplication, instanziiere von dort mein QMainWindow aus der dll und rufe den obigen Code mit dem QNetworkAccessManager auf. Jetzt friert der Code an der Stelle ein, wo ich den get-Request absende.

Bei stackoverflow habe ich eine ähnliche Fehlerbeschreibung gefunden:
http://stackoverflow.com/questions/1186 ... led-in-dll
Der Ansatz zur Lösung auf meine Situation übertragen ist etwa folgendermaßen:

In der dll, die den get-Request absetzt, existiert soweit keine Instanz von QApplication. Ich müsste also in der dll eine QApplication initialisieren, die mit der in meinem Python Skript erzeugten QApplication-Instanz identisch ist. Mir ist nur nicht klar, wie ich das machen soll (und ob das überhaupt in die richtige Richtung geht): Ich kann zwar aus meiner Python-Anwendung den qApp - Zeiger an meine dll übergeben, nur was mache ich damit? Der Kopierkonstruktor von QApplication ist privat ... wie kann ich sicherstellen, dass an der Stelle des get-Requests dasselbe QApplication Objekt existiert? (Und ist das überhaupt die Ursache für das eigentliche Problem ...?)
bobcat
Beiträge: 125
Registriert: 21. April 2010 14:51

Re: QNetworkAccessManager friert ein (bei Aufruf aus dll)

Beitrag von bobcat »

Okay, ich habe mir die

Code: Alles auswählen

qApp->sessionId()
und den

Code: Alles auswählen

qApp->sessionKey()
direkt nach dem Start meiner Python-Anwendung in meinem Python-Skript und direkt vor meinem Aufruf des get-Requests in der dll angeschaut. Die sind identisch; die PyQt Python-Bindings tragen also Sorge, dass hier die Anwendung korrekt aufgesetzt wird. Ich muss also nicht versuchen, wie unten vermutet, in den Klassen meiner dll ein QApplication an den Start zu bringen. Nur, weshalb friert dann der get-Request ein?
bobcat
Beiträge: 125
Registriert: 21. April 2010 14:51

Re: QNetworkAccessManager friert ein (bei Aufruf aus dll)

Beitrag von bobcat »

Ich bin bei der Spurensuche etwas weiter gekommen:

Der Fehler tritt nicht nur auf, wenn ich den Code über die dll aufrufe, sondern auch, wenn ich in der C++ Welt bleibe und den Code aus dem Visual Studio heraus debugge. Hier friert die Ausführung des Programms jedoch nicht ein, sondern es wird eine Ausnahme geworfen, die vom Visual Studio großzügig übergangen wird. Hier die entsprechende Aufrufhierarchie:

QNetworkAccessManager::get(const QNetworkRequest & request)
QNetworkAccessManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest & req, QIODevice * outgoingData)
QNetworkConfigurationManager::QNetworkConfigurationManager(QObject * parent)
qNetworkConfigurationManagerPrivate()
connManager()
QNetworkConfigurationManagerPrivate::initialize()
QNetworkConfigurationManagerPrivate::updateConfigurations()

Hier bin ich in folgender Codezeile:

Code: Alles auswählen

void QNetworkConfigurationManagerPrivate::updateConfigurations()
{
    QMutexLocker locker(&mutex);

    if (firstUpdate) {
        if (qobject_cast<QBearerEngine *>(sender()))
            return;

        updating = false;

#ifndef QT_NO_LIBRARY
        QBearerEngine *generic = 0;

        QFactoryLoader *l = loader();
        foreach (const QString &key, l->keys()) {
            QBearerEnginePlugin *plugin = qobject_cast<QBearerEnginePlugin *>(l->instance(key));
            if (plugin) {
                QBearerEngine *engine = plugin->create(key);
           ...
Beim ersten Durchlauf der foreach - Schleife ist

Code: Alles auswählen

key = "generic"
Beim zweiten Durchlauf des foreach ist

Code: Alles auswählen

key = "nativewifi"
und es wird folgende Ausnahme geworfen, wenn

Code: Alles auswählen

QBearerEngine *engine = plugin->create(key);
abgearbeitet wird:

Eine Ausnahme (erste Chance) bei 0x74a9c42d in myDemo.exe: 0x000006A6: Die Bindungsnummer ist unzulässig.

Hat jemand eine Idee, wo der Fehler liegt? (Ich bin in Qt 4.8.6 unterwegs)
bobcat
Beiträge: 125
Registriert: 21. April 2010 14:51

Re: QNetworkAccessManager friert ein (bei Aufruf aus dll)

Beitrag von bobcat »

Direkt bevor die Ausnahme geworfen wird, werden übrigens
C:\Windows\SysWOW64\wlanapi.dll
C:\Windows\SysWOW64\wlanutil.dll
geladen.
Antworten