LabVIEWForum.de
Problem beim Einbinden einer DLL - 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: Problem beim Einbinden einer DLL (/Thread-Problem-beim-Einbinden-einer-DLL)

Seiten: 1 2


Problem beim Einbinden einer DLL - preacha - 22.01.2008 10:05

Hey vielen Dank für die Mühe.
So bekomme ich allerdings ganz komische Werte raus.
Wenn ich einfach ein Array mit 4-Byte-Single Werten nehme stimmen die Ergebnisse eigentlich.
Ist also schon ok so.

Jetzt habe ich aber noch ein anderes Problem.
Wenn ich mein Programm ausgeführt habe, wieder stoppe und danach die Eigenschaften
von irgendwelchen Objekten aufrufen will stürzt mir das komplette LabVIEW ab, mit
irgendwelchen Read oder Write fehlern.
Das passiert aber nicht immer, nur ab und zu.
Wird da irgendwie der Speicher nicht freigegeben?
Muss ich das manuel machen?


Problem beim Einbinden einer DLL - rolfk - 22.01.2008 13:41

' schrieb:Hey vielen Dank für die Mühe.
So bekomme ich allerdings ganz komische Werte raus.
Wenn ich einfach ein Array mit 4-Byte-Single Werten nehme stimmen die Ergebnisse eigentlich.
Ist also schon ok so.

Jetzt habe ich aber noch ein anderes Problem.
Wenn ich mein Programm ausgeführt habe, wieder stoppe und danach die Eigenschaften
von irgendwelchen Objekten aufrufen will stürzt mir das komplette LabVIEW ab, mit
irgendwelchen Read oder Write fehlern.
Das passiert aber nicht immer, nur ab und zu.
Wird da irgendwie der Speicher nicht freigegeben?
Muss ich das manuel machen?

Also wenn Du sagst, dass es mit einem Float-Array ausser dem Interleaving funktioniert, verwendet die DLL als enum scheinbar ein uInt32. Nun wahrscheinlich eigentlich nicht da ein C Compiler normalerwiese den kleinsten unsigned int benützt, der nötig ist um den höchsten positiven Wert des enums zu representieren.

Da Dein enum ja nur vier Werte enhält, also 0, 1, 2, und 3 wäre das halt ein uInt8. Aber die meisten unter Windows erstellten Applikationen und DLLs verwenden ein default alignment, was heisst dass ein Element in einem Cluster immer auf einem ganzzahligen Vielfachen des kleineren der beiden folgenden Werte beginnt:

1) Der Objektsize des Elementes (hier 4 bytes für Single float)
2) Dem Default alignment, normalerweise 8 unter 32 bit Windows

Dein Array sieht im Speicher also so aus:

[code]Adresse


Problem beim Einbinden einer DLL - preacha - 22.01.2008 14:20

Danke für die Info, nun wird mir einiges klar.
Und LabVIEW stürzt auch nicht mehr ab ^_^


Problem beim Einbinden einer DLL - preacha - 28.01.2008 15:47

Ich habe mein Programm jetzt mal soweit fertig, dass es funktioniert.
Habe versucht so viel wie möglich in Sub-Vi´s auszugliedern.
Trotzdem habe ich jetzt irgendwie das Gefühl, dass es schlampig gemacht ist^^
Hat vielleicht jemand Lust mal drüber zu schauen?
Da kann man bestimmt noch einiges von der Struktur verbessern und ich wäre für jeden Denkanstoß sehr dankbar.


Problem beim Einbinden einer DLL - rolfk - 29.01.2008 11:53

' schrieb:Ich habe mein Programm jetzt mal soweit fertig, dass es funktioniert.
Habe versucht so viel wie möglich in Sub-Vi´s auszugliedern.
Trotzdem habe ich jetzt irgendwie das Gefühl, dass es schlampig gemacht ist^^
Hat vielleicht jemand Lust mal drüber zu schauen?
Da kann man bestimmt noch einiges von der Struktur verbessern und ich wäre für jeden Denkanstoß sehr dankbar.

Hallo, ich habe die VIs noch nicht im einzelnen betrachtet aber hier schon mal ein paar allgemeine Anregungen.

1) Es ist sinnvoll, um Deinen VIs einen Prefix zu geben (LG200 scheint mir hier durchaus gut geeignet). Die Chance dass Du in einem grösseren Programm plötzlich mehrer Messwerte.vi oder Status.vi bekommst sind einfach zu gross. Da VIs einen globalen Namespace innerhalb eines Projektes haben bekommst Du dann Namenskollisionen. Eine Alternative ist um eine Library davon zu machen die allen VIs innerhalb dieser Library auch so etwas wie einen Prefix mitgibt.

2) mfc71.dll und msvcr71.dll kannst Du nicht einfach mit Deiner Library mitkopieren. Zwar in diesem Fall nicht weil es illegal wäre (sind ja redistributable DLLs und dürfen also mitkopiert werden) sondern weil Windows sie innerhalb des VI Directories schlichtweg nie finden wird. Diese DLLs werden wohl durch Deine LJIF.DLL gebraucht und deshalb hat LabVIEW selber keinen Einfluss darauf von wo sie geladen werden. Bei LJIF.DLL selber kann LabVIEW die DLL selbst noch suchen, und tut das auch unter anderem im Directory wo das VI das diese verwendet steht. Aber die indirekten Abhängigkeiten kann LabVIEW nicht kennen und werden von der DLL direkt angefragt. Dort sucht aber Windows dann nur in:

1. Speicher selber, wenn die DLL schon geladen wurde
2. Application Directory (wo LabVIEW.exe oder Deine built application steht)
3. Windows Directory
4. System Directory
5. alle Directories die in der Path Variablen vorkommen

Da diese DLLs normalerweise auf neueren Windows Systemen ohnehin im Systemverzeichnis anwesend sind geht es gut (werden aber die von Dir mitgekopierten DLLs gar nicht verwendet). Wenn diese DLL aber nicht anwesend sind hilft das Kopieren der DLLs in das VI Directory aus Gründen der obengenannten Suchpfade auch nichts.

3) Datenabhängigkeit: Was Du hier gemacht hast ist eine Kollektion von VIs und die wiederum in andere VIs hineingepflanzt ohne irgendwelche Datenabhängigikeit. Das funktioniert zwar für kleine Demoapplikationen aber ist innerhalb einer richtigen Applikation kaum zu integrieren und noch viel weniger zu managen.
Dein LJ-G Interface.vi ist eine willkürliche Anordung von drei völlig verschiedenen Operationen ohne jede Datenabhängigkeit. Der Aufrufer muss genau wissen dass man das VI erst mit dem connect Boolean = true aufrufen muss bevor man etwas anderes machen kann. Das ist kein intuitiv verwendbares VI.

Schau Dir mal als Anregung die Library an die ich für die Beckhoff Busklemmen hier gepostet habe. Das gibt Dir eine Idee wie man die Funktionen gestalten kann, um eine saubere Datenflussabhängigkeit durch verbinden des Error Clusters zu bekommen.

Mache aus den verschiedenen DLL Aufrufen jeweils ein SubVI, das einen error in und error out Cluster besitzt.
Das sähe dann so aus dass Du ein

LG200 Connect.vi
LG200 Get Measurement.vi
LG200 Trigger.vi
LG200 Set Auto Zero.vi (Nullen)
LG200 Error Convert.vi (ReportValues aber dann in einen error Cluster)

Die VIs Status.vi und Messwerte.vi machen keinen Sinn innerhalb der Library für so ein Device. Status.vi hat eh nicht viel Sinn da Du normalerweise die Datenaquisition innerhalb Deines Programmes eh intelligenter machen musst als stur in einer Loop immer pollen. Ein Error während des Connects beispielweise ist zwar schön zu sehen in Deinem Hauptprogramm, aber Du wirst di DAQ Loop doch echt so programmieren müssen dass sie einen reconnect versucht, statt danach stur Daten lesen zu wollen.

Ob Du Messwerte.vi verwenden willst innerhalb einer Applikation ist Dir überlassen. Aber bitte entferne die Property Node im Lesen Case. Der verursacht nähmlich höchstens Verwirrung und ist viel langsamer als das direkte Lesen des Shiftregisters. Zudem verwendest Du das Shiftregister gar nicht sondern verwendest das Ausgangsterminal als Zwischenspeicher, was auch noch mögliche Probleme bei Userinteraktionen mit dem Frontpanel geben kann.

Rolf Kalbermatter


Problem beim Einbinden einer DLL - preacha - 30.01.2008 08:35

Vielen Dank für deine ausführliche Hilfe.
Ich werde mir mal dein Programm genauer anschauen und versuchen mich an deine Tipps zu halten.


Problem beim Einbinden einer DLL - baliik - 24.09.2008 16:34

Hallo,

meine Problem ist in der Nähe von preacha's Problem,
ich benutze 2D Laser (also Linie Laser) von Keyence, also mann bekommt ein Profil, wenn mann ein mal abtastest. Jede Profil hat 640Punkte, das heißt 640 Werte. Also ein Array.
ich versuche dieses Laser durch sein DLL messen lassen und einlesen, habe aber Schwierigkeiten. Einige "wichtige"<_< Funktion, die ich durch DLL in LabVIEW erzeugt hab, kann ich nicht richtig benutzen. Die heißen "LJIF_GetMeasuramentValue" und "LJIF_GetProfileData". Wichtig ist bei mir, GetProfileData.

Ich muss als Abtastart extern Trigger benutzen. Das funktioniert. Mit einem Knopf in LabVIEW löse ich erfolgreich ein Trigger aus, und es wird "(ich glaube)in Steuerungsgerät" von Laser abgespeichert. Danach muss ich aber durch eine Funktion diese Dateien auslesen. Diese Funktion ist wahrscheinlich "LJIG_GetProfilDatei".

Wer lust hat kann vom Zip-Datei ganze Projekt schauen.

Ich bin dankbar für jede kleine Schritte RolleyesZeitung2

Gruß,

MUUcar

Lv85_img


Problem beim Einbinden einer DLL - jg - 24.09.2008 19:10

So, mal schauen:

Code:
LJIF_GetProfileData(IN LJIF_PROFILETARGET ProfileTarget, OUT LJIF_PROFILE_INFO* pProfInfo, OUT FLOAT* pProfile, IN INT nCount)

OUT FLOAT* pProfile heißt nicht unbedingt, dass das "nur" ein einzelner Float-Value ist, das kann auch ein Array sein (es wird ja nur der Pointer auf den ersten Wert eines Bereiches zurückgegeben).

Dann mal Doku lesen:
[attachment=14518]
Ja, das bestätigt doch meine Vermutung mit dem Array, und nCount gibt die Größe des Arrays an.

Probiers also mal mit folgender Definition:
[attachment=14519]
[attachment=14520]

Gruß, Jens


Problem beim Einbinden einer DLL - baliik - 25.09.2008 11:51

Mail
Klasse!Top2

ein dickes Dankeschön Jens, Big Grin

Grüße!