LabVIEWForum.de
Delphi-DLL mit globalen Variablen - Druckversion

+- LabVIEWForum.de (https://www.labviewforum.de)
+-- Forum: LabVIEW (/Forum-LabVIEW)
+--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein)
+---- Forum: DLL & externer Code (/Forum-DLL-externer-Code)
+---- Thema: Delphi-DLL mit globalen Variablen (/Thread-Delphi-DLL-mit-globalen-Variablen)



Delphi-DLL mit globalen Variablen - Bärbel - 13.07.2009 14:25

Hallöle,

ihr werdet es nicht glauben, aber wir hängen immer noch mit dieser Delphi-DLL rum, wegen der ich euch schon vor ca. 1 Jahr genervt habe.
Immerhin sind wir inzwischen an einem definierten Problem angekommen:
Ich rufe im LabVIEW-Programm 3 DLL-Funktionen auf, Init (bei Programmstart), Step (in einer While-Schleife), Final (bei Programmende).
Init öffnet zwei Dateien (mit globalen Handles oder wie auch immer das bei Delphi genannt wird) und legt große, globale Speicherbereiche an, die mit sinnvollen Werten vorbelegt werden.
Step liest die Dateien und nutzt die Speicherbereiche für Berechnungen. Einzelne Werte aus diesem Speicherbereich werden werden als double zurückgeliefert. (Die Rückgabe wurde bereits mit Dummy-Werten überprüft.)
Final schließt die Dateien und gibt den globalen Speicher wieder frei.

Es scheint so zu sein, dass die 3 DLL-Aufrufe (konfiguriert auf: beliebiger Thread) aber nicht auf dieselben Speicherbereiche zuzugreifen. Wird die Funktionalität des LabVIEW-Programms als Delphi-Programm geschrieben, das dann die DLL aufruft, funktioniert aber alles tadellos.

Kann mir vielleicht jemand erklären, wie LabVIEW DLL-Aufrufe handhabt? Was passiert mit globalen DLL-Variablen?

Ist doch eine tolle Frage fürs Sommerloch Cool

Grüße aus einem wirklich eklig warmen Büro,
Bärbel


Delphi-DLL mit globalen Variablen - rolfk - 13.07.2009 18:15

LabVIEW tut mit DLL Aufrufen nichts besonderes. Es ruft die Funktionen halt einfach auf und wenn Du Sie als reentrant konfigurierst dann tut es das halt von beliebigen Threads aus. Das hat auf wirklich globale Variablen absolut keinen Einfluss, ausser dass Du da Race Konditionen verursachen kannst.

Aber ich weiss nicht wie global Deine globalen Variablen sind und auch nicht ob Delphi da etwas eigenes macht wie automatisch Thread Local Storage (TLS) anlegen. Wenn es das tut sollte es wohl eine Möglichkeit geben um Delphi zu sagen das wirklich Global zu machen. Wie weiss ich leider nicht, meine Delphi Kenntnisse beschränken sich hauptsächlich auf die griechische Sagenwelt.

Kanns auch mal probieren alle Funktionsaufrufe im UI Thread zu machen. Wenn das Multithreading das Problem ist sollte es damit funktionieren auch wenn das Performance mässig natürlich meist nicht gewünscht ist, aber es gibt zumindest Anhaltspunkte wo man weitersuchen soll.

Rolf Kalbermatter


Delphi-DLL mit globalen Variablen - Bärbel - 14.07.2009 09:55

' schrieb:LabVIEW tut mit DLL Aufrufen nichts besonderes. Es ruft die Funktionen halt einfach auf und wenn Du Sie als reentrant konfigurierst dann tut es das halt von beliebigen Threads aus. Das hat auf wirklich globale Variablen absolut keinen Einfluss, ausser dass Du da Race Konditionen verursachen kannst.

Aber ich weiss nicht wie global Deine globalen Variablen sind und auch nicht ob Delphi da etwas eigenes macht wie automatisch Thread Local Storage (TLS) anlegen. Wenn es das tut sollte es wohl eine Möglichkeit geben um Delphi zu sagen das wirklich Global zu machen. Wie weiss ich leider nicht, meine Delphi Kenntnisse beschränken sich hauptsächlich auf die griechische Sagenwelt.

Kanns auch mal probieren alle Funktionsaufrufe im UI Thread zu machen. Wenn das Multithreading das Problem ist sollte es damit funktionieren auch wenn das Performance mässig natürlich meist nicht gewünscht ist, aber es gibt zumindest Anhaltspunkte wo man weitersuchen soll.
Danke für den Hinweis mit den Race Conditions, aber die können hier wirklich nicht auftreten. Ich hatte der Vollständigkeit halber aber bereits ausprobiert, ob es einen Unterschied macht, wenn ich die Aufrufe im UI Thread laufen lasse. Macht es aber nicht.

Also werden wir noch ein wenig im Delphi-Nebel stochern müssen, von dem ich leider auch nicht allzu viel verstehe. Schon gar nicht von den Compiler-Direktiven. Seltsam ist halt nur, dass die DLL-Aufrufe mit einem Delphi-Testprogramm funktionieren. Da wird dann gerne mit dem Finger auf mich (bzw. LabVIEW) gezeigt, seufz...

Trotzdem danke für die Anwort,
Bärbel


Delphi-DLL mit globalen Variablen - IchSelbst - 14.07.2009 20:51

' schrieb:Also werden wir noch ein wenig im Delphi-Nebel stochern müssen, von dem ich leider auch nicht allzu viel verstehe.
Welche Delphi-Version verwendest du denn?

Kast du mal die Schnittstelle der DLL zeigen?


Delphi-DLL mit globalen Variablen - rolfk - 15.07.2009 06:32

' schrieb:Danke für den Hinweis mit den Race Conditions, aber die können hier wirklich nicht auftreten. Ich hatte der Vollständigkeit halber aber bereits ausprobiert, ob es einen Unterschied macht, wenn ich die Aufrufe im UI Thread laufen lasse. Macht es aber nicht.

Also werden wir noch ein wenig im Delphi-Nebel stochern müssen, von dem ich leider auch nicht allzu viel verstehe. Schon gar nicht von den Compiler-Direktiven. Seltsam ist halt nur, dass die DLL-Aufrufe mit einem Delphi-Testprogramm funktionieren. Da wird dann gerne mit dem Finger auf mich (bzw. LabVIEW) gezeigt, seufz...

Trotzdem danke für die Anwort,
Bärbel

Also wenns mit dem UI Execution System dasselbe macht, dann ist es ganz sicher nicht TLS oder so was. Das UI Execution System ist in LabVIEW nähmlich ein ganz besonderes weil es nur aus einem Thread besteht der garantiert über die Lebensdauer des Prozesses immer derselbe bleibt.

Das sieht mir mehr aus wie wenn Du die DLL dynamisch lädst und wieder auslädst zwischen jedem Aufruf. Dazu fallen mir nur zwei Möglichkeiten ein im Moment.

1) Du lädst und unlädst die VIs selber dynamisch, etwa als Test Sequenzen innerhalb von Test Stand oder einer ähnlichen (selbstgestrickten) Test Sequenzumgebung.

2) Du verwendest das neue Call Library Feature um den Pfad zur DLL dynamisch als Parameter zur CLN anzugeben anstatt wie früher statisch im Konfigurationsdialog.

Oder Du machst in der DLL selber irgendwie was was die globalen Variablen immer wieder neu initialisiert.

Rolf Kalbermatter