' schrieb:ich habe versucht das ganze jetzt so zu lösen.
Ich kann mit deinem SubVI nicht wirklich arbeiten. Viel zu breit, viel zu wenige SubVI.
Mach ein neues mit z.B. einer Statemachine. Für jeden Schritt einen eigenen Case. Nach jedem Zugriff auf die DLL muss abgefragt werden, ob der Rückgabewert <> Null ist. Bei <> Null wird GetLastError abgefragt und in einem String abgezeigt.
' schrieb:Ich kann mit deinem SubVI nicht wirklich arbeiten. Viel zu breit, viel zu wenige SubVI.
Mach ein neues mit z.B. einer Statemachine. Für jeden Schritt einen eigenen Case. Nach jedem Zugriff auf die DLL muss abgefragt werden, ob der Rückgabewert <> Null ist. Bei <> Null wird GetLastError abgefragt und in einem String abgezeigt.
Also das mit dem GetLastError() funzt bei LabVIEW leider nicht. GetLastError ist ein dummes Überbleibsel aus der single-threaded Windows 3.x und früheren Zeiten. Windows speichert per Thread einen GetLastError() Wert ab. Das Problem ist dass LabVIEW hochgradig multi-treaded ist und nur eingeschränkte Kontrolle über die exakte Ausführung von VIs in Threads zulässt. Wenn Du die Call Library Node als reentrant konfigurierst kann diese in jedem der ungefähr 4 bis 8 Threads ausgeführt werden die LabVIEW derzeitig per Execution System anlegt. Das Execution System ist so ein bisschen das unterste Niveau wo Du an LabVIEW sagen kannst wie es mit Multithreading umgehen soll, da man einzelne VIs verschiedenen von 6 Execution Systems zuweisen kann. Das Problem ist hier dass die Ausführung der eigentlichen DLL Funktion und des anschliessend GetLastError() hier in völlig verschiedenen Threads geschehen kann und normalerweise auch tut.
Die naheliegende Lösung um die zwei DLL Nodes als non-reentrant zu konfigurieren und dadurch im einzigen garantiert single-threaded Execution System, dem User Interface Execution System, auszuführen funktioniert leider auch nicht. LabVIEW führt nämlich in diesem Execution System auch alle Interaktionen mit dem OS aus die nicht multithreading-sicher sind. Dazu gehören viele OS Aufrufe wie etwa das Zeichnen des User Interfaces und die meisten dieser Windows API Funktionen beinflussen diesen GetLastError() auch. Zu der Zeit wo das LabVIEW Diagram dann die GetLastError() Funktion aufruft um den Status des vorigen DLL Aufrufs zu lesen, hat LabVIEW ziemlich sicher schon andere Windows APIs aufgerufen die diesen Wert ebenfalls beinflussen. Das Lesen des GetLastError() direkt vom LabVIEW Diagramm ist deshalb im besten Fall unzuverlässig aber gibt meist ganz einfach falsche Informationen zurück. Wenn GetLastError() wirklich nötig ist dann gibt es nur zwei zuverlässige Lösungen. Entweder Multithreading in LabVIEW ganz ausschalten (gibt da ein INI Token dafür aber diese Lösung ist ziemlich brutal) oder eine Wrapper DLL schreiben die sowohl den eigentlichen Aufruf der DLL Funktion und den anschliessenden GetLastError() Aufruf in eine einzige Funktion verpackt. Der Aufruf eines DLL Knotens ist nämlich garantiert in einem einzigen Thread.
Rolf Kalbermatter
' schrieb:LabVIEW führt nämlich in diesem Execution System auch alle Interaktionen mit dem OS aus die nicht multithreading-sicher sind.
![Huh Huh](images/smilies/lvfsmilies/fun/huh.gif)
(naja, eigentlich hab ich nichts anderes erwartet).
Wenn unser Rolf K. spricht erfährt man immer interresante Sachen. Wie hier über GetLastError auf dem OS.
Hinweis:
Das GetLastError, das ich oben erwähnt habe, ist eine Funktion aus der DLL ZEBSDK. [*grübel*] Und ich gehe mal davon aus, das wird nicht nur ins OS weitergeleitet.
' schrieb:Das GetLastError, das ich oben erwähnt habe, ist eine Funktion aus der DLL ZEBSDK. [*grübel*] Und ich gehe mal davon aus, das wird nicht nur ins OS weitergeleitet.
Ohhhhh!
Da ist mir entgangen. In dem Falle wird es wohl ganz einfach eine globale Variable sein. Ich denke mal dass sich die Programmierer nicht die Mühe gemacht haben um hier eine Variable per aufrufenden Thread anzulegen. Solange man dann in so einem Fall die DLL schön sequentiell anruft wäre der GetLastError() wohl schon aussagekräftig. Aber ob das wirklich so ist müsste in der Dokumentation zur DLL stehen oder wenn nicht, ausführlich getestet werden.
Rolf Kalbermatter