LabVIEWForum.de
DLL-Aufruf mit structure**-Wert - 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: DLL-Aufruf mit structure**-Wert (/Thread-DLL-Aufruf-mit-structure-Wert)



DLL-Aufruf mit structure**-Wert - astraios - 20.03.2007 15:24

Hallo,

ich hab mal wieder ein kleines Problem mit einem meiner LabVIEW-Programme:

Ich möchte eie DLL Funktion aufrufen. Das ist an sich kein Problem, hab ich schon öfters gemacht.
Aber diese DLL überfordert mich jetzt leicht. Der Funktionsaufruf sieht folgendermaßen aus:

int myfunction(mystruct** data)


hinter data soll im Endeffekt eine Strukturstehen - und Strukturen in LabVIEW Cluster ummodeln ist auch kein Problem (Als U8 Array byteweise auslesen...).
Doch hier komm ich einfach nicht an die Daten ran.

In der Call Libraray Function Node gebe ich den Parameter wie folgt an:

Typ: Array
Datentyp: U8
Dimensionen: 1
Array-Format: Array Datenzeiger

Damit bekomm ich verständlicherweise nicht die Daten an sich sondern nur eine Speicheradresse (4 Byte = 32 bit lang). Im "Funktionsprototyp" steht ja bei LV mit obigen Einstellungen auch nur "long _myfunction@4(unsigned char *data);" anstatt "... **data);"

Wenn ich jetzt aber bei Array-Format auf Array-Handle stelle, steht da dann zwar "... **data);" - aber dummerweise verabschiedet sich LabVIEW beim Ausführen.
Wie komme ich jetzt an die Daten ran? Kann ich aus der Speicheradresse was machen?

Vielen Dank im Voraus für die HilfeWink


Viele Grüße,

Robert


DLL-Aufruf mit structure**-Wert - IchSelbst - 20.03.2007 16:18

' schrieb:ich hab mal wieder ein kleines Problem mit einem meiner LabVIEW-Programme:
[*rofl*]

Zitat:int myfunction(mystruct** data)
Sieht schlecht aus. Schreibt die DLL Daten nach LV oder liest die DLL Daten von LV? Oder übergibt die DLL einen Pinter auf Daten an LV?

[*grübel*]

Eigenlich alles egal. Pointer auf Pinter geht so oder so mit LV nicht.


Zitat:Damit bekomm ich verständlicherweise nicht die Daten an sich sondern nur eine Speicheradresse (4 Byte = 32 bit lang). Im "Funktionsprototyp" steht ja bei LV mit obigen Einstellungen auch nur "long _myfunction@4(unsigned char *data);"
Dieses ansich sind schon die Daten.

Zitat:anstatt "... **data);"
Das wäre der Pointer. Das geht aber nicht.

Zitat:Wenn ich jetzt aber bei Array-Format auf Array-Handle
Das ist ja auch ein Handle. Was nicht zwangsläufig gleichbedeutend ist mit "Pointer auf Pointer".


Beantworte mir mal bitte meine obige Frage. Dann kann ich weiter überlegen.


DLL-Aufruf mit structure**-Wert - astraios - 20.03.2007 16:28

Danke für Deine Antwort.

Die DLL-Funktion schreibt Daten und ich versuche, sie aus "data" zu lesen. Wenn ich den Aufruf wie oben beschrieben (Array Datenzeiger) mache, bekomme ich einen Wert, der bei jedem Aufruf um 152 größer wird (was ungefähr der Größe der Struktur entspricht, die ich erwarte) - das deutet ja irgendwie auf eine Speicheradresse hin, oder? Aber ich will nicht die Adresse, ich will den Inhalt!Sad


//edit: Zum Thema Pointer auf Pointer geht eh nicht in LV: Das wär schlimm. Die Struktur stellt nämlich eine verkettete Liste dar, in der jedes Element einen Zeiger auf das nachfolgende Element enthält... krieg schon langsam Kopfschmerzen...


DLL-Aufruf mit structure**-Wert - IchSelbst - 20.03.2007 16:58

' schrieb:Die DLL-Funktion schreibt Daten und ich versuche, sie aus "data" zu lesen.
Gut, ich glaube ich weis jetzt was du (respektive die DLL) machst: Die DLL erstellt einen Datensatz (Speicherbereich innerhalb der DLL) und gibt einen Pointer auf diesen Speicherbereich zurück. Dieser Pointer wird in data gespeichert.

Ich denke darüber nach - und werden den Fall in mein DLL-Tutorial aufnehmen.


Zitat:Wenn ich den Aufruf wie oben beschrieben (Array Datenzeiger) mache, bekomme ich einen Wert, der bei jedem Aufruf um 152 größer wird (was ungefähr der Größe der Struktur entspricht, die ich erwarte) - das deutet ja irgendwie auf eine Speicheradresse hin, oder?
Jawohl: Ein Pointer (der selbst einen Wert von größer 0x004xxxxx hat?) auf einen Datenbereich.

Zitat:Aber ich will nicht die Adresse, ich will den Inhalt!
Verstehe ich. Wink

Zitat://edit: Zum Thema Pointer auf Pointer geht eh nicht in LV: Das wär schlimm.
Das ist schlimm.

Zitat:Die Struktur stellt nämlich eine verkettete Liste dar, in der jedes Element einen Zeiger auf das nachfolgende Element enthält
Das ist noch schlimmer, weil eben auch nicht möglich. Auch hier werde ich nochmals nachdenken.

Zitat:... krieg schon langsam Kopfschmerzen...
Schon mal was von Wrapper-DLL gehört?


DLL-Aufruf mit structure**-Wert - IchSelbst - 20.03.2007 20:22

' schrieb:int myfunction(mystruct** data)
Theoretisch könnte man hier "Array-Handle" nehmen. Aber eben nur theoretisch.

Ein Array-Handle ist - guckst du auch in der LV-Hilfe - ein Pointer auf eine Datenstruktur. Die ersten Int32 sind die Längen der Dimensionen. Je nach Anzahl der Dimensionen stehen also zuerst einige Int32. Danach kommen dann die Daten. Für ein eindimensionales I8-Array heißt das also: Zuerst vier Byte, die die Anzahl der nachfolgenden Bytes angeben, dann die nachfolgenden Daten.

Immerhin kann man sich mit "Array-Handle" von der DLL einen Pointer geben lassen auf einen Datenbereich, der in der DLL liegt. Würde dein DLL-Struct mit der Länge des Structs beginnen, so würde das wunderbarerweise funktionieren. Nur wer beginnt schon in weiser Voraussicht seinen Struct mit dessen Länge.

Was weiterhin gar nicht geht, sind Pointer in Cluster.

Pointer (auf Anwenderebene) sind ein veraltetes Hilfmittel, LV ist eine moderne Programmiersprache. Leider schließt sich das gegenseitig aus.


DLL-Aufruf mit structure**-Wert - astraios - 21.03.2007 09:27

Guten Morgen,

danke für Deine ausführlichen Antworten. Auch wenn diese mich wenig optimistisch stimmen Sad

Zitat:der selbst einen Wert von größer 0x004xxxxx hat?)
Ja.

Zitat:Schon mal was von Wrapper-DLL gehört?
Nein, aber jetzt nachgeschaut... wäre ein Ausweg. Würde die Sache aber ungemein umständlicher machen als geplant war... naja, sind ja eh nur 3 oder 4 Funktionen in der API, die so dämliche Pointerpointer verwenden... die anderen könnt ich ja theoretisch direkt ansprechen.

Zitat:Würde dein DLL-Struct mit der Länge des Structs beginnen
Tut's leider nicht.

Zitat:Pointer (auf Anwenderebene) sind ein veraltetes Hilfmittel, LV ist eine moderne Programmiersprache. Leider schließt sich das gegenseitig aus.
Durch die "moderne Programmiersprache" fühle ich mich irgendwie entmündigt...


Also schonmal vielen Dank für Deine Unterstützung! Über wundersame Lösungen meines Problems würde ich mich nach wie vor sehr freuenWink

Viele Grüße

Robert


p.S.: Dieses LVF-Usertreffen Dingens über dem Mauszeiger nervt ungemein...


DLL-Aufruf mit structure**-Wert - astraios - 21.03.2007 10:24

HEUREKA! Ich hab's!

Hier bin ich fündig geworden.

Es gibt in der LabVIEW Bibliothek eine Funktion namens "MoveBlock", der man eine Speicheradresse und Länge übergibt und die dann den Speicherbereich ausgibt.

Also ändere ich meinen DLL-Aufruf so, dass ich nur einen Zeiger auf U32 für "data" verwende. Diesen U32-Wert, der ja die Adresse der Struktur darstellt, geb ich dem MoveBlock Knoten und der gibt mir die Daten im gewünschten U8-Array aus.

Und genauso müsste das mit den Pointern in der Struktur selbst (verkettete Liste) dann auch klappen.

[attachment=5795]

[attachment=5796]


Also nochmal vielen Dank für die engagierte Hilfe!


Viele Grüße

Robert


DLL-Aufruf mit structure**-Wert - IchSelbst - 21.03.2007 12:11

' schrieb:HEUREKA! Ich hab's!
Hier bin ich fündig geworden.
Hast du sehr gut gemacht! Damit hast du vielen Anwendern geholfen. [*lob*]

Zitat:Es gibt in der LabVIEW Bibliothek eine Funktion namens "MoveBlock",
Ja, der gut alte move() - und wie er immer heißt. Jetzt also auch in LV.

Zitat:Und genauso müsste das mit den Pointern in der Struktur selbst (verkettete Liste) dann auch klappen.
Sehe ich erstmal auch so.


DLL-Aufruf mit structure**-Wert - rolfk - 14.06.2007 23:19

' schrieb:Hast du sehr gut gemacht! Damit hast du vielen Anwendern geholfen. [*lob*]

Ja, der gut alte move() - und wie er immer heißt. Jetzt also auch in LV.

Jetzt! Lach!

Der steckt in LabVIEW seit Version 2.5 damals aber nur für CINs erreichbar. Aber seit minimal 5.0 kann man den per DLL Aufrufknoten direkt erreichen. Habe ich auf den LabVIEW Foren und Info-LabVIEW wiederholt in den letzten 6 oder 7 Jahren oder so haarfein erklärt, bevor jemand bei NI scheinbar dachte, dass man das auch mal in einem Beispiel dokumentieren könnte.

Rolf Kalbermatter


DLL-Aufruf mit structure**-Wert - FaSch - 04.06.2008 14:18

Ich habe das Problem in umgekehrter Reihefolge...

ich muß mit LabVIEW eine DLL erstellen, in der eine Funktion einen Parameter vom Typ "struct** array" beinhaltet!

Hat jemand ne Idee, wie man sowas machen könnte?

Danke schonmal für eure Antworten ;-)