LabVIEWForum.de
Buffer - 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: Buffer (/Thread-Buffer--13636)

Seiten: 1 2 3 4


Buffer - IchSelbst - 26.02.2007 23:15

' schrieb:Also soweit ich weiß meinst du einen c-code selber schreiben
Jawohl. (Obwohl man natürlich nicht "C-Code" schreibt, sondern "Programme". C-Code benutzt man zum Schreiben von Programmen.)

Zitat:welcher dies dann umwandelt bzw einen pointer erstellen der auf das array zeigt!
Im Prinzip genau so.

Zitat:Muss es eine DLL sein, oder kann das auch nur ein c-code sein?
Im Prinzip kann es sein, was es will. Deine LV-Applikation muss nur damit kommunizieren können. Eine DLL hat da halt diverse Vorteile. Du kannst natürlich auch ein EXE-File nehmen (also eine "C-Code-Applikation") und z.B. Messages austauschen.

Zitat:Gibt es da von LabVIEW bereits Vorlagen?
Nee. Nicht dass ich wüsste.

Im übrigen hab' ich deine Wrapper-DLL eigentlich schon fertig. Es nützt dir nur nix, weil ich selbst in den nächsten drei Wochen keine Zeit habe sie zu testen und zu dokumentieren. Tongue


Buffer - Semtex - 05.03.2007 08:10

1. Frage:

' schrieb:>welcher dies dann umwandelt bzw einen pointer erstellen der auf das array zeigt!

Im Prinzip genau so.

So, der übermäßige C-Programmierer war ich noch nie, also wie erstelle ich etwas derartiges? Ich übergebe der DLL (dem C-Code) mein Array, und wie gebe ich dann als "Rückgabewert" den Zeiger darauf aus?


2. Frage:
Unsere Übergabe einer Struktur an die DLL (kein Pointer) soll laut unserem Projektleiter auch nicht funktionieren.

> Der C-Code

GT_InitChannels(HANDLE hDevice,_AIN analogCh,_DIO digitalCh);

typedef struct // structure used to define analog channels
{
BOOL ain1; // TRUE: scan channel 1, FALSE: do not scan channel 1
BOOL ain2; // ...
BOOL ain3;
BOOL ain4;
BOOL ain5;
BOOL ain6;
BOOL ain7;
BOOL ain8; // TRUE; scan channel 8, FALSE: do not scan channel 8
}_AIN;


typedef struct // structure used to define digital lines
{
BOOL scan; // TRUE to scan digital lines, FALSE: do not scan digital lines
BOOL dio1_direction; // TRUE sets direction "IN", FALSE sets direction "OUT" (DIO 1)
BOOL dio2_direction; // TRUE sets direction "IN", FALSE sets direction "OUT" (DIO 2)
}_DIO;

> Unsere Lösungsidee (alt)
Jedes Strukturelement wird einzeln übergeben

[attachment=5466]

> Logische Lösungsidee
Die Strukturelemente werden zu einem Array zusammengefügt und dann erst der DLL übergeben. Jedoch stürtzt hier das Programm beim ausführen sofort ab.

[attachment=5467]

unsigned long GT_InitChannels(long hDevice, Array1DLong **_AIN, Array1DLong **_DIO);

3. Frage:
Das ewige Problem der Datenbeschaffung

GT_GetData(HANDLE hDevice,_BUFFER_ST *buffer,LPOVERLAPPED lpOvl);

Unsere Idee wäre wie folgt

[attachment=5470]

Ob sie funktioniert ist eine andere Idee. Wie dann der Funktionsaufruf der DLL etc. aussieht wissen wir nicht. Also die DLL soll einen Zeiger auf das Array erstellen, und zusammengepackt mit den anderen 2 Werten an die 2. DLL (GetData) übergeben werden.


Buffer - IchSelbst - 05.03.2007 10:00

' schrieb:1. Frage:
Ich übergebe der DLL (dem C-Code) mein Array, und wie gebe ich dann als "Rückgabewert" den Zeiger darauf aus?
Überhaupt nicht, weil sinnlos.
Wegen: Wenn du am Eingang des DLL-Knotens einen Draht, also Daten respektive einen Speicherbereich, anschließt, dann ist nämlich genau dieser Datenbereich nach dem Ende des DLL-Knotens nicht mehr verfügbar. Demzufolge ist auch der Pointer darauf sinnlos (respektive sogar falsch). Überall dort, wo ein Draht aufhört, hört auch die "Beständigkeit" der Daten respektive des Speicherbereiches auf. Wenn du in einer DLL auf einen Datenbereich außerhalb der DLL (auch mittels eines Pointers) schreiben willst, so musst du diesen Datenbereich (respektive den Draht) am Ausgang des DLL-Knotens anschließen. Dann sind die Daten nach dem Ende des DLL-Aufrufes noch vorhanden.

Was nicht - nein, das ist nicht wahr - was nur sehr schwierig geht, ist: Der DLL einen Pointer übergeben, sodass die DLL auch dann noch, wenn der DLL-Knoten bereits beendet ist, auf die Daten außerhalb der DLL zugreifen kann. Dann würden praktisch in der DLL ein Thread quasi parallel zu LV laufen.

Zitat:2. Frage:
Unsere Übergabe einer Struktur an die DLL (kein Pointer) soll laut unserem Projektleiter auch nicht funktionieren.
> Der C-Code
GT_InitChannels(HANDLE hDevice,_AIN analogCh,_DIO digitalCh);
Wurde sowas nicht in einem anderen Thread hier behandelt - und erfolgreich abgeschlossen?

Wenn da im Prototyp steht "_AIN analogCH" dann ist das eine ganz normale "Variable" (die halt auf 8 Werten U8 oder U32 besteht). Da sollte eine Übergabe von 8 einzelnen Werten funktionieren.

Zitat:> Unsere Lösungsidee (alt) Jedes Strukturelement wird einzeln übergeben
Könnt ihr mit Sicherheit ausschließen, dass das falsch ist?

Zitat:> Logische Lösungsidee
Die Strukturelemente werden zu einem Array zusammengefügt und dann erst der DLL übergeben.
Das geht aber nicht: Wenn die DLL am Stack 8 Werte erwartet, kannst du ihr nicht einfach nur einen Wert (nämlich einen Pointer auf ein Array. Hast du so?) geben. => Absturz.

Zitat:3. Frage:
Das ewige Problem der Datenbeschaffung
GT_GetData(HANDLE hDevice,_BUFFER_ST *buffer,LPOVERLAPPED lpOvl);
Es wird auch ein ewiges bleiben. Irgendwo hat alles seine Grenzen.
Denk nur an die Dinos. Kaum fällt da so ein kleiner Stein auf die Erde, sterben sie vollends aus. Wer überlebt? Die kleinen, katzenartigen Säuger (, die es bereits schon gab). [*OhIchSchweifeAb*]
Einen Pointer in einer Struktur zu haben, die selbst als Pointer überegben wird, geht nicht. - Zumindest solange nicht, bis ich (oder wer auch immer) das Gegenteil per Sourcecode bewiesen habe. Das hängt damit zusammen, dass ein Datenbereich nur solange gültig ist, wie der Draht dazu existiert. Kein Draht, kein Datenbereich, kein permanenter Pointer.
Und nicht, dass du jetzt denkst, da zieh ich einfach einen Draht auf ein Schieberegister einer Whileschleife. So einfach ist das nicht. Ab einer Verzweigung ist der Darht neu, also ein anderer Speicherbereich. Sowas würde nur mit Ausgängen eines DLL-Knotens gehen.


Buffer - Semtex - 05.03.2007 10:27

' schrieb:dann ist nämlich genau dieser Datenbereich nach dem Ende des DLL-Knotens nicht mehr verfügbar. Demzufolge ist auch der Pointer darauf sinnlos (respektive sogar falsch). Überall dort, wo ein Draht aufhört, hört auch die "Beständigkeit" der Daten respektive des Speicherbereiches auf. Wenn du in einer DLL auf einen Datenbereich außerhalb der DLL (auch mittels eines Pointers) schreiben willst, so musst du diesen Datenbereich (respektive den Draht) am Ausgang des DLL-Knotens anschließen. Dann sind die Daten nach dem Ende des DLL-Aufrufes noch vorhanden.

Was nicht - nein, das ist nicht wahr - was nur sehr schwierig geht, ist: Der DLL einen Pointer übergeben, sodass die DLL auch dann noch, wenn der DLL-Knoten bereits beendet ist, auf die Daten außerhalb der DLL zugreifen kann. Dann würden praktisch in der DLL ein Thread quasi parallel zu LV laufen.

Okay, ich verstehe. Kurz gesagt, es geht nicht *verdammt*

' schrieb:Wurde sowas nicht in einem anderen Thread hier behandelt - und erfolgreich abgeschlossen?

Wenn da im Prototyp steht "_AIN analogCH" dann ist das eine ganz normale "Variable" (die halt auf 8 Werten U8 oder U32 besteht). Da sollte eine Übergabe von 8 einzelnen Werten funktionieren.

Könnt ihr mit Sicherheit ausschließen, dass das falsch ist?

Das geht aber nicht: Wenn die DLL am Stack 8 Werte erwartet, kannst du ihr nicht einfach nur einen Wert (nämlich einen Pointer auf ein Array. Hast du so?) geben. => Absturz.

Mein Projektpartner hat das gepostet, und es funktioniert "theoretisch" auch, also der Rückegabewert bestätigt einen gültigen Aufruf, jedoch gibt es gewisse Personen welche nicht glauben das ein C-Programm mit 3 Eingangsvariablen mit insgesamt 12 Eingangswerten von LV aus aufgerufen werden kann.

Mit Sicherheit können wir es nicht ausschließen, ginge erst wenn unser GT_GetData funktionieren würde, was laut oben ja unmöglich ist.

' schrieb:Es wird auch ein ewiges bleiben. Irgendwo hat alles seine Grenzen.
Einen Pointer in einer Struktur zu haben, die selbst als Pointer überegben wird, geht nicht. - Zumindest solange nicht, bis ich (oder wer auch immer) das Gegenteil per Sourcecode bewiesen habe. Das hängt damit zusammen, dass ein Datenbereich nur solange gültig ist, wie der Draht dazu existiert. Kein Draht, kein Datenbereich, kein permanenter Pointer.
Und nicht, dass du jetzt denkst, da zieh ich einfach einen Draht auf ein Schieberegister einer Whileschleife. So einfach ist das nicht. Ab einer Verzweigung ist der Darht neu, also ein anderer Speicherbereich. Sowas würde nur mit Ausgängen eines DLL-Knotens gehen.

Hmm... verdammt.

Dennoch danke für die bisherige Hilfe! Ich hoffe wir finden einen Weg das noch irgendwie hinzubekommen!


Buffer - IchSelbst - 05.03.2007 11:13

Nur ganz schnell:

' schrieb:jedoch gibt es gewisse Personen welche nicht glauben das ein C-Programm mit 3 Eingangsvariablen mit insgesamt 12 Eingangswerten von LV aus aufgerufen werden kann.
Das kommt auf den Typ der Variablen an, die ausgetauscht werden sollen.

Bei Typgleichheit gilt die Anzahlgleichheit auch für die Parameter.

Bei "Typungleichheit" gilt die Anzahlgleichheit für die übergebenen Bytes. Erschwerend aber kommt erstens hinzu, dass der "ungleiche Typ" ein kombinierter Typ sein muss => Pointer geht nicht, weil nicht kombiniert. Zweitens müssen die Basistypen übereinstimmen: BOOL in "_AIN" == BOOL in "8*Bool".

Ersteres beinhaltet automatisch das letztere. Und da eine Typungleichheit zwischen "_AIN" und "8*Bool" besteht, gilt letzteres.


Buffer - IchSelbst - 05.03.2007 23:11

Ich hab dir mal meine TestDLL hier eingestellt. Sie dient unter anderem auch als Beispiel für das DLL-Tutorial, das ich gerade schreibe - wenn ich denn Zeit dafür finde. Ein Abschnitt in dem Tutorial befasst sich mit dem Datenaustausch zwischen LV und einer DLL. Das von dir verwendete Verfahren zum Datenaustausch wird ein Teil dieses Abschnittes sein.

Ich hoffe, ich habe dich bezüglich des Datenmodells richtig verstanden.

Schau mal, ob du damit klar kommst - respektive ob es brauchbar ist.


Buffer - Semtex - 06.03.2007 15:41

' schrieb:Ich hab dir mal meine TestDLL hier eingestellt. Sie dient unter anderem auch als Beispiel für das DLL-Tutorial, das ich gerade schreibe - wenn ich denn Zeit dafür finde. Ein Abschnitt in dem Tutorial befasst sich mit dem Datenaustausch zwischen LV und einer DLL. Das von dir verwendete Verfahren zum Datenaustausch wird ein Teil dieses Abschnittes sein.

Ich hoffe, ich habe dich bezüglich des Datenmodells richtig verstanden.

Schau mal, ob du damit klar kommst - respektive ob es brauchbar ist.

Hallo!

also erstmal vielen Dank für deine Hilfe!
Finde ich super von dir das du eine TestDLL zur Verfügung stellst!Smile
Leider kann ich das VI nicht öffnen da wir die Version 7.2 besitzen! Wär es möglich das VI in Version 7.2 zu bekommen?

thx im vorraus!


Buffer - jg - 06.03.2007 17:50

<div align="left">Hallo,

hier ein 2-fach konvertiertes VI (8.20->8.0, dann einiges Editieren, da DLL-Knoten unter 8.0 keinen Fehlereingang/Ausgang hat, dann 8.0->7.1).

Hoffentlich funktionierts.

[attachment=5511]

MfG, Jens

P.S.: Was für eine Sonderversion LabVIEW hast du eigentlich? Von Version 7.20 habe ich noch nie etwas gehört. Oder meinst du 7.1.1?</div>


Buffer - Semtex - 12.03.2007 09:37

' schrieb:<div align="left">P.S.: Was für eine Sonderversion LabVIEW hast du eigentlich? Von Version 7.20 habe ich noch nie etwas gehört. Oder meinst du 7.1.1?</div>
sorry meinte natürlich 7.1!


Buffer - Semtex - 19.03.2007 08:16

So, anstatt das ich alles in LV mache habe ich mich nun entschlossen meine eigene DLL zu schreiben. Doch auch jetzt habe ich einige Probleme. Zum Beispiel weiß ich nicht was die komischen Sonderzeichen in meinem Funktionsprototyp bedeuten, habt ihr eine Ahnung? (keine Sorge, der DLL Name wurde mit Absicht rausgelöscht)

[attachment=5737]

Also wenn jemand weiß ob das irgend einen Einfluss auf unser Programm hat so möge er jetzt sprechen *g*