MainWindow von Interface Polling (dll) entkoppeln

Alles rund um die Programmierung mit Qt
Antworten
embweb
Beiträge: 15
Registriert: 15. Oktober 2009 12:30
Wohnort: Alling
Kontaktdaten:

MainWindow von Interface Polling (dll) entkoppeln

Beitrag von embweb »

Hallo,

nachdem ich nun trotz Lesen der Manuals und Bücher zu Qt an einem Punkt hänge, möchte ich dann doch mal hier im Forum um Rat fragen...

Mein Problem: Ich habe ein Interface, zu dem der Hersteller eine Lib, Header und eine dll mitliefert. Um die dll zu verwenden, habe ich eine Klasse erstellt (InterfaceCom), die mit QLibrary diese dll lädt und mir die benötigten Funktionen daraus bereitstellt (als Methode der Klasse).
Dann habe ich eine zweite Klasse, die das MainWindow funktional abbildet (ui mit QtDesigner erstellt) - so wie man das in der Literatur als Basis-Beispiel findet.
In der main() werden beide Klassen dann als Objekt erzeugt und ich übergebe den Pointer meiner InterfaceCom an das MainWindow.

Funktional läuft in meiner InterfaceCom ein QTimer mit 10ms, der beim Auslösen den Empfangspuffer meines Interface ausliest (Methode der Klasse) und die Daten dann in einem Array (public) der Klasse ablegt.
Diese Daten liest dann das MainWindow alle 250ms und aktualisiert damit die Felder/Widgets des Fensters. Die 250ms habe ich ebenfalls mit einem QTimer realisiert. Beide QTimer sind mit signal/slot mit den Methoden verknüpft.

Mein Problem: Sobald ich den QTimer für den poll-Betrieb des Interface starte, kann ich die Widgets des MainWindow bedienen und meine Daten werden auch empfange, klicke ich aber ausserhalb des Fensters, beendet sich meine Applikation. Auch wenn ich mit der Maus das Fenster verschiebe, beendet sie sich.
Wenn ich den Timer auf 30ms oder mehr setze, stürzt sie auch ab... obwohl die 2 Telegramme/10ms locker zu verarbeiten wären.
Beim Debuggen bekomme ich eine SIGSEGV Fehlermeldung von Windows, was auf ein Speicherzugriffsproblem vermuten läßt ?

Ich vermute, dass es damit zusammenhängt, dass alles in einer Ereignisverarbeitung des MainWindow hängt und dann das Lesen zum Blockieren führt. Meine Frage ist nun, wie ich das jetzt entkoppeln kann. Meine Befürchtung ist, wenn ich QThreads verwende, dass ich da ggf. nur den Bottleneck der Datenübergabe an eine andere Stelle verlagere...

Wie würdet Ihr da konzeptionell vorgehen ?

Für Tipps oder auch Verweise/Links auf die gute Literatur, wäre ich sehr dankbar.
In der späteren Zielapplikation, ein Roboter, werde ich noch mehr Interfaces und Daten verarbeiten müssen; wenn ich jetzt schon bei den paar Daten konzeptionell Probleme habe, brauch ich die anderen Interfaces erst garnicht anbinden, bzw. sehe beim Roboter vielleicht gleich noch einen Griff zum Schieben vor... :wink:

Vielen Dank jedenfalls und Gruß,

Marcus
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Konzeptionell gehört das in einen QThread
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Troll.Soft
Beiträge: 190
Registriert: 18. Juni 2008 09:52
Wohnort: Hamburg

Re: MainWindow von Interface Polling (dll) entkoppeln

Beitrag von Troll.Soft »

embweb hat geschrieben:Beim Debuggen bekomme ich eine SIGSEGV Fehlermeldung von Windows, was auf ein Speicherzugriffsproblem vermuten läßt ?
Diese furchtbare Fehlermeldung hatte ich auch einmal und habe tagelang recherchiert um hinter die Lösung zu kommen. Die Datenübergabe von einer Dll zur anderen klappte nicht. Übergeben wurden STL-Container. Habe die STL-Container gegen Qt-Container ausgewechselt und die Welt war wieder in Ordnung.
Mein Ansatz bei Deinem Problem wäre erstmal die Gui ad Akta zu legen und zu versuchen nur die Schnittstelle zum Laufen zu bringen. Ausgabe der Daten über qDebug() << ... QThread nicht vergessen :)

tschüß
Troll.Soft
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Habe die STL-Container gegen Qt-Container ausgewechselt und die Welt war wieder in Ordnung.
Berichtige: Scheinbar in ordnung ! :lol:

Dll Schnittstellen:
Du hasst sagen wir mal mehrere Level an Binaerkompatiblitaet von Code.

Level 0 - C-Strukturen / Pods / Funktionszeiger - unproblematisch weil binaer genau sprezifiziert, compilerunabhaengig
Level 1 - Abstrakte Klassen - Problematisch durch Name Mergling, Ausrichtung und Position der VTable, parameterausrichtung nicht spezifiziert - machen aber compiler der gleichen generation meist gleich
Level 2 - ausgepraegte Klassen - zu Level 1 kommt noch die Ausrichtung der Daten an Speichergrenzen, sowie einige andere Optimierungen hinzu. Binaerabbild abhaengig von Compiler / Optimierungs - Einstellungen
Level 3 - compilergenerierter Code - Templates allgemein. Sehr Optimierungs und Compiler / Abhaengig schon die kleinste aenderung an den Flags kann ne aenderung im binaerabbild bewirken.

Generell:
Willst Dir auf lange Sicht Aerger ersparen, solltest du Level 2 und 3 meiden.
Eigentlich sprechen die Fakten von 2 und 3 gegen die Konzepte einer Dll ... 3 solltest generell meiden!
Bei Level 2 auf linux Systemen kann man noch diskutieren, weil die haben das Problem mit der compilerabhaengigkeit ned so durch ihren Systemcompiler. Unter windows ist das wesentlich kritischer.

Probleme in die du laeufst iss meist, aenderst Du mal ein fitzelchen an deiner App, dann musst die Dll meist mit neu erstellen und ausliefern.
D.H. App - Version und Dll-Version muessen immer 1:1 uebereinstimmen ... und bei heutigen Speicher und Performance Faehigkeiten der aktuellen Rechner sollt man dann doch lieber libs nehmen, die paar mehr byte in der exe sind dann den Aerger mit der Versionierung nimmer Wert.

Ciao ...
embweb
Beiträge: 15
Registriert: 15. Oktober 2009 12:30
Wohnort: Alling
Kontaktdaten:

Danke für Eure Unterstützung

Beitrag von embweb »

Hallo,

erst einmal vielen Dank für Eure Unterstützung hier im Forum. Auf die erste Antwort von Christian81 mit Link auf "Newbies bitte beachten!" hatte ich erst noch überlegt, ob ich meine Frage nicht gleich wieder zurückziehe... :roll:

Zu den Antworten: Ich habe vor 2 Jahren schon einmal eine Bootloader-App für die Konsole mit dem Interface geschrieben, die ohne Probleme lief. Die Funktionen der dll haben immer einen Rückgabewert und als Parameter meist einen Wert oder eine Pointer auf eine Struktur (Byte/uint8_t Buffer).
Somit fällt das schon mal auf den von RHBaum beschriebenen Level 0 und sollte keinen Ärger machen.

Die vom Hersteller mitgelieferte Lib ist für Borland oder Microsoft MFC kompiliert und fliegt mir beim Einbinden gleich um die Ohren. Daher ja auch der Ansatz, die dll zu verwenden.

Ich habe gestern mal noch weiter probiert und auch parallel den Thread-Ansatz getestet. Das Problem scheint aber unabhängig davon zu sein und ich bin mir jetzt sicher, das es am Rückgabewert der _Read Funktion liegt, die ich in einer while()-Schleife aufrufe, solange der Rückgabewert signalisiert, dass der Buffer noch Daten enthält.
Wenn der Rückgabewert schon nicht korrekt ist, kann auch der Pointer auf die Daten falsch sein und dann lese ich irgendwo im Speicher und Windows verpasst mir die SIGSEGV...

Vielleicht liegt es auch am Byte-Alignment, und der Compiler übersetzt den Zugriff auf meine Arrays anders, als in der dll (Byte aligned) verwendet.

Happy Debugging...
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Es kann auch an unterschiedlichen Compilern (bzw. msvc runtimes) liegen
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Antworten