Hallo,
Ich habe zwei ganz einfache VIs, welche nur je eine Funktion einer externen DLL aufrufen. Das funktioniert auch wunderbar. Solange die VIs unter Windows geöffnet sind, kann ich sie ohne Probleme jederzeit ausführen. Wehe aber, wenn ich die VIs mal schliesse via [X]-Button, dann stürzt gleich mein komplettes Labview ab. Ich habe das mit Labview 8.6. und 2011 ausprobiert, es ist immer dasselbe.
Liegt das jetzt an der DLL oder an Labview? Bzw. wie kann ich am schnellsten herausfinden, wo hier das Problem ist? Die DLL ist leider nicht von mir geschrieben.
Danke für Hinweise!!
Gruß
Sima
(16.01.2012 15:52 )sima schrieb: [ -> ]Hallo,
Ich habe zwei ganz einfache VIs, welche nur je eine Funktion einer externen DLL aufrufen. Das funktioniert auch wunderbar. Solange die VIs unter Windows geöffnet sind, kann ich sie ohne Probleme jederzeit ausführen. Wehe aber, wenn ich die VIs mal schliesse via [X]-Button, dann stürzt gleich mein komplettes Labview ab. Ich habe das mit Labview 8.6. und 2011 ausprobiert, es ist immer dasselbe.
Liegt das jetzt an der DLL oder an Labview?
Die Antwort ist sehr simpel: kann sowohl als auch!!!! Allerdings nicht in dem Sinn dass LabVIEW was falsch macht hier (ist mir in meinen letzten 15 Jahren LabVIEW Programmierung in diesem Gebiet nie untergekommen) sondern dass Du in Deinem VI einen Fehler gemacht hast in der Konfiguration der Parameter. Das kann ein Datentypfehler sein, das kann genau so gut ein Fehler sein, dass Du bei einem Ausgabeparameter der aufgerufenen Funktion keinen Buffer bereitgestellt hast, oder schlichtweg nicht genug oder zuviel Parameter konfiguriert hast. Alternativ kann natürlich die DLL einen Bug haben, durch den sie irgendwo ins Nirvana einen Speicherzugriff macht und dadurch LabVIEWs Datenstrukturen zerstört. Da die DLL aber ja wohl nicht von der heissen Stricknadel kommt (lassen wir es zumindest hoffen), würde ich doch GAANZ fest erstmal in Deinem LabVIEW VI alle Parameter, doppelt, dreifach und vierfach checken, und wenn Du kein versierter C Programmierer bist, dies auch noch durch einen solchen machen lassen.
Erst wenn Dir ein guter C Programmierer, der idealerweise auch was von LabVIEW versteht, bestätigt hat, dass Deine VIs in Ordnung erscheinen, hat es überhaupt einen Sinn, den DLL Programmierer anzusprechen.
Zudem: Wenn Du etwas mehr Informationen preisgegeben hättest, wie zum Beispiel über was für eine DLL es geht, die entsprechenden Header Files, UND API Beschreibungen beigefügt hättest, UND Deine erstellten VIs angehängt hättest, wäre die Antwort ziemlich sicher sehr viel spezifischer ausgefallen. Aber die meisten Leute denken immer noch, dass ein Spezialist einfach so erraten kann was sie falsch gemacht haben. Schliesslich sehen sie den Code vor sich, also kann das doch der Spezialist auch, oder!
Hallo,
Danke für deine Hinweise. Die Funktionen der DLL starten und beenden einen TCP-Client und haben keine weiteren Über- oder Rückgabewerte.
Ich habe im Call Library Function Node die Thread-Konifguration geändert von "Run in UI thread" zu "Run in any thread".
Vorerst habe ich jetzt keine Abstürze mehr. Aber eigentlich dürfte es doch auch bei der Option "Run in UI thread" zu keinem Abturz kommen oder?
Gruß
Sima
(17.01.2012 16:22 )sima schrieb: [ -> ]Hallo,
Danke für deine Hinweise. Die Funktionen der DLL starten und beenden einen TCP-Client und haben keine weiteren Über- oder Rückgabewerte.
Ich habe im Call Library Function Node die Thread-Konifguration geändert von "Run in UI thread" zu "Run in any thread".
Vorerst habe ich jetzt keine Abstürze mehr. Aber eigentlich dürfte es doch auch bei der Option "Run in UI thread" zu keinem Abturz kommen oder?
Gruß
Sima
Das hängt ganz davon ab wo und wie die DLL TCP anspricht. Winsock ist relativ unkritisch lässt aber extrem viele Möglichkeiten zu, die bei den asynchronen APIs, die eben nicht ganz asynchron sind, schon mal irgendwelche obskuren Threading Issues verursachen können.
AktiveX ist eine regelrechte Katastrophe da dies normalerweise voraussetzt dass man die entsprechenden Objekte immer vom selben Thread aus ausruft. Das tut in LabVIEW nur der UI Thread, (oder wenn Du die ActiveX Knoten explizit verwendest) aber der hat wieder eigene ziemlich haarige Abhängigkeiten vom Windows Message Dispatcher, der auch beim Dispatchen von DCOM Methoden eine sehr wichtige Rolle spielt, sodass es da durchaus zu kompletten Lockouts kommen kann.
Last but not least gibt es natürlich noch .Net, ebenfalls eine möglicherweise abenteurliche Sache, sicher wenn das Threading Konzept von LabVIEW sich mit dem Threading Konzept von .Net vertragen muss, ohne dass die beiden explizit voneineander wissen. Dazu kommt noch die etwas pseudo-mässige Implementation des asynchronen Winsock APIs die dank Altlasten doch auch wieder in die Windows Message Dispatch Queue einhackt und Du hast ein Rezept für viele Stunden Debugging und Haareraufen (übrigens auch ohne LabVIEW, aber das macht das Ganze meistens noch ein wenig spannender).
BSD Socket Programmierung ist auch nicht gerade Kleinkinderkost, aber zumindest beim Threading muss man sich normalerweise nicht noch extra Gedanken machen, ausser den normalen Race-Konditions usw. die bei jeder Multithreadingprogrammierung wichtig sind.
Hallo,
Um die Sache abzuschließen:
Ich habe mich mit dem Entwickler der DLL unterhalten. Der TCP Client wird auf Winsock basierend programmiert. Das Problem lag aber woanders.
Die DLL, die ich in Labview einbinde, bezieht während der Lauftzeit Qt-Ressourcen. Es gibt scheinbar verschiedene Möglichkeiten Labview auf Qt zu migrieren.
Der erste Ansatz, der einen Absturz verursachte, war über die WinAPI-Funktion "GetModuleHandle", die
einen Handle auf eine Instanz der übergeordneten Win32 Applikation (in diesem Fall Labview) liefert und an Qt weitergibt.
Der zweite Ansatz, der keinen Absturz verursacht hat war die Einsprungsfunktion DLLMain der WinAPI zu benutzen, die schon von sich aus einen parameter "hInstance" liefert
zur Migration von Win32 Applikation auf Qt.
Der Verdacht ist, dass der erste Ansatz einen zu großen Speicherbereich bezieht für den Handle und beim Zerstören der Instanz nicht alles wieder komplett freigibt und dann
Labview beim Entladen der DLL aus dem Speicher (Schliessen der VIs) abstürzt.
Beim zweiten Ansatz wird durch Benutzen der vorgegebenen Funktion nur genauso viel Speicher bezogen/zerstört, wie für die Instanz benötigt wird. Somit kommt es zu keinem Absturz.
Gruß
Sima