03.05.2007, 08:26
Beitrag #1
|
Predator
LVF-Gelegenheitsschreiber
Beiträge: 62
Registriert seit: Mar 2007
8.50
2006
DE
29393
Deutschland
|
Daten einer Struktur aus LV einer DLL übergeben
hallo liebes LV-Forum,
ich habe wiedermal ein problem und bitte um hilfe...
ich möchte einen datensatz einer struktur übergeben. laut beschreibung der karte wird in der dll ein pointer *IN_WRITE_SPECIAL auf eine struktur übergeben. die struktur besitzt verschiedene formate (int, uchar, bool...usw). wie mache ich das, wenn ich in lv den datensatz übergeben möchte? mit der call library funktion kann ich ja einen zeiger auf die struktur nur in ein bestimmtes format übergeben. es kommt doch bestimmt sehr häufig vor das man karten auf dieser weise konfiguriert; datensatz aus lv einer struktur übergiebt. gibt es dafür lösungen? habe mir mal die wrapper.dll angeschaut, was mir aber nicht weiterholfen hat.
noch ein verständnis problem: wenn ich daten in format bool habe, wäre doch die adressierung z.b. 4.0, 4.1, usw... wenn jetzt in der struktur nach dem bool z.b. ein uchar folgt, wäre ja die nächte freie adresse dafür 5? also könnte man doch die daten in bool auch als char formatieren und die zahl 1 oder 0 übergeben?
ich hoffe ihr könnt mir helfen...
mfg dennis
|
|
|
03.05.2007, 11:06
Beitrag #2
|
IchSelbst
LVF-Guru
Beiträge: 3.696
Registriert seit: Feb 2005
11, 14, 15, 17, 18
-
DE
97437
Deutschland
|
Daten einer Struktur aus LV einer DLL übergeben
' schrieb:ich möchte einen datensatz einer struktur übergeben. laut beschreibung der karte wird in der dll ein pointer *IN_WRITE_SPECIAL auf eine struktur übergeben. die struktur besitzt verschiedene formate (int, uchar, bool...usw). wie mache ich das, wenn ich in lv den datensatz übergeben möchte? mit der call library funktion kann ich ja einen zeiger auf die struktur nur in ein bestimmtes format übergeben. es kommt doch bestimmt sehr häufig vor das man karten auf dieser weise konfiguriert; datensatz aus lv einer struktur übergiebt.
Jawohl, alles klar. So würde es jeder haben wollen (die Datenübergabe mein ich).
Zitat:gibt es dafür lösungen?
Nein, bisher nicht. Mir ist zumindest keine bekannt, die ohne Tricks genau das macht.
Das Problem ist der Pointer an sich. In einer Datenflußsteuerung gibt es keine expliziten Pointer. Warum sich da also beim DLL-Knoten Arbeit machen? Schön wäre, wenn man einfach ein Cluster anschließen könnte und im Knoten sagen "Pointer auf Daten". Das geht aber nicht.
Lösung:
Einen Stream (= String) generieren, anschließen und "PChar, Zeiger auf Daten" wählen. Im Prinzip müsstes du alle Daten des Clusters per flatten to string hardcore-typ-konvertieren und hintereinander in einen String schreiben. Dann hast du genau das, was die DLL erwartet. Ob du mit flatten to string einen String erzeugst oder die Daten in ein Array of int8 konvertierst ist egal. Hauptsache es kommt ein Stream heraus, also ein zusammenhängender Datenbereich, auf dessen Anfang ein Pointer zeigen kann.
Zitat:noch ein verständnis problem: wenn ich daten in format bool habe, wäre doch die adressierung z.b. 4.0, 4.1
Nein.
Der Typ Bool ist je nach Programmiersprache int8 oder int32. In LV int32. Das mit den Bitpositionen geht zwar auch, dann ist es aber kein expliziter Bool. Der Typ Bool wird wie eine normale Int-Zahl gespeichert. Lediglich der Wertebereich ist anders. Bool kennt nur zwei Werte: "Null" und "ungleich Null" (wobei "ungleich Null" praktischerweise, aber auch nur in den Fällen einer Zuweisung, mit Eins gleichzusetzen ist)
Zitat:also könnte man doch die daten in bool auch als char formatieren und die zahl 1 oder 0 übergeben?
Genau so wird es gehandhabt.
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
|
|
|
04.05.2007, 07:39
Beitrag #3
|
Predator
LVF-Gelegenheitsschreiber
Beiträge: 62
Registriert seit: Mar 2007
8.50
2006
DE
29393
Deutschland
|
Daten einer Struktur aus LV einer DLL übergeben
hallo... erstmal vielen dank für deinen vorschlag!
ich habe mir nochmal die funktionsbeschreibung angeschaut und musste feststellen, das es offensichtlich kein pointer ist, sondern ein parametersatz, der übertragen wird.
hier der funktionsprototyp: PrepSpecial(HANDLE hDevive, IN_WRITE_SPECIALStructSpecial, ULONG* pSimpleStatus)
IN_WRITE_SPECIAL ist die Struktur auf die der Pointer *PIN_WRITE_SPECIAL zeigt.
so mein gedachtes vorgehen: ich clustere die strukturtypen nacheinander zusammen, konvertiere nach string und übergebe den zeiger (char) aus LV an die DLL. Kann das so funktionieren? von LV seite her geht das bestimmt, jedoch mache ich mir sorgen ob der parametersatz richtig von der DLL gelesen wird. ich habe immernoch mit dem speicher probleme: wenn ich eine struktur habe mit unterschiedlichen formaten, wie sieht das im speicher aus? habe ich einzelne speicherblöcke (z.b. int32 ->4byte länge) in den die daten im jeweiligen format stehen (z.b. int8 -> nur die ersten 8bit sind daten) und dann folgt der nächste speicherblock mit int32?
das alles kann man bestimmt irgendwo nachlesen... was ich wohl auch machen muss.
wenn mir jemand das bestätigen oder helfen könnte bezüglich des vorgehens mit dem parametersatz, würde es mir weiterhelfen. ich muss alle parametersätze nacheinander an die karte senden, bis ich testen kann ob die karte das annimmt.
vielen dank im Voraus...
|
|
|
04.05.2007, 08:32
Beitrag #4
|
IchSelbst
LVF-Guru
Beiträge: 3.696
Registriert seit: Feb 2005
11, 14, 15, 17, 18
-
DE
97437
Deutschland
|
Daten einer Struktur aus LV einer DLL übergeben
' schrieb:das es offensichtlich kein pointer ist, sondern ein parametersatz, der übertragen wird.
Auch kein Problem.
Hast du das DLL-Tutorial mal angekuckt, besonders Punkt 4.5. Datensätze des Typs STRUCT können durch eine Liste der Elemente aus dem struct ersetzt werden.
Zitat:: ich clustere die strukturtypen nacheinander zusammen, konvertiere nach string und übergebe den zeiger (char) aus LV an die DLL. Kann das so funktionieren?
Nein.
Das würde ja nur funktionieren, wenn die DLL einen Pointer erwartet. Nun scheint sie deinen Angaben ja nicht "1 Pointer" zu erwartet, sondern "1 Struct aus 8 Daten". Es müssen jetzt als 8 Parameter übergeben werden anstelle von 1.
Zitat:wenn ich eine struktur habe mit unterschiedlichen formaten, wie sieht das im speicher aus?
Du musst die LV-Seite an die DLL-Seite anpassen. Umgekehrt geht nicht. Die Größe der einzelnen Parameter innerhalb des Struct liegt fest - nämlich über den Typ des Parameters. Und genau diesen Typ musst du dann im DLL-Knoten einstellen. Wie es im Speicher aussieht, muss dich eigentlich nicht interessieren. Für dich ist nur wichtig, dass der Typ passt. Wenn im Struct der Reihe nach I32, I8, I8, I32 liegt, dann gibst du das genauso auch im DLL-Knoten an: I32, I8, I8, I32.
Zitat:z.b. int8 -> nur die ersten 8bit sind daten
Hinweis:
Bei einem I8 kann man nicht sagen "nur die ersten 8 Bit sind Daten". Ein I8 hat nur 8 Bit. Zweite oder Dritte 8 Bit gibt es nicht.
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
|
|
|
04.05.2007, 09:37
Beitrag #5
|
|
|
04.05.2007, 12:05
Beitrag #6
|
IchSelbst
LVF-Guru
Beiträge: 3.696
Registriert seit: Feb 2005
11, 14, 15, 17, 18
-
DE
97437
Deutschland
|
Daten einer Struktur aus LV einer DLL übergeben
Erstens:
Hast du verifiziert, dass der Aufruftyp - also stdcall oder cdecl - richtig ist?
Zweitens:
Was mich jetzt noch verwundert ist, dass da i8 benutzt werden. Eigentlich dürften i8 gar nicht gehen. Normalerweise werden die Daten mit dem PUSH-Befehl auf den Stack gelegt. Der kann aber nur I32 oder I16, nicht aber I8. Vielleicht solltest du mal probieren, auch die uchars als u32 zu übergeben.
Ich muss das mit den I8 in einer Struktur respektive über den Stack selbst mal auspobieren.
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
|
|
|
04.05.2007, 12:35
Beitrag #7
|
Predator
LVF-Gelegenheitsschreiber
Beiträge: 62
Registriert seit: Mar 2007
8.50
2006
DE
29393
Deutschland
|
Daten einer Struktur aus LV einer DLL übergeben
hallo...
der aufruftyp ist richtig in cdecl!
das mit den konvertierungen habe ich auch gecheckt... aber ohne erfolg!
aber trotzdem vielen dank...
ich versuche es weiter, vielleicht habe ich selbst einen versteckten fehler reingebaut...
gruss
dennis
|
|
|
05.05.2007, 22:09
Beitrag #8
|
IchSelbst
LVF-Guru
Beiträge: 3.696
Registriert seit: Feb 2005
11, 14, 15, 17, 18
-
DE
97437
Deutschland
|
Daten einer Struktur aus LV einer DLL übergeben
Hallo Predoator!
Bei deinem Problem der Übergabe einer Struktur über den Stack an eine DLL bin ich zu folgendem Ergebnis gekommen.
Code:
typedef struct_IN_WRITE_SPECIAL
{
BOOL bSperre
UCHAR uchSendeimpluls
UCHAR uchSendeenergie
BOOL bSendeempfangsmode
.
.
.
}
Die Abfolge dieser Struktur ist folgende: Bool1 = 4 Byte; UCHAR1 = 1 Byte; UCHAR2 = 1 Byte; Bool2 = 4 Byte; etc. Das an sich ist kein Problem. Jede Programmiersprache (respektive der Prozessor) kann den unterschiedlich langer Zugriff handeln. Einmal eben 4 Byte für Bool1 = normaler 32Bit-Zugriff. Zweimal 1 Byte = quasi-normaler 8Bit-Zugriff. Bool2 = nicht nomaler 32Bit-Zugriff. Die Nicht-Normalität liegt darin, dass die 32Bit nicht an einer durch vier teilbaren Adresse anfangen. Der Prozessor kann das zwar, aber eigentlich nur über Umwege. Eine solche Struktur würde man als "gepackte Struktur" bezeichnen. (Eine nicht gepackte Struktur wäre es, wenn auch die 1Byte-Werte in einem 32Bit-Speicher abgelegt werden; nicht gepackte Strukturen sind Standard). Soweit sogut.
Wenn nun eine Funktion als Parameter eine (gepackte) Struktur wie diese hat, dann verlangt sie wohl auch genau diese Bit-Aufteilung für diesen Parameter im Speicher.
Im DLL-Knoten sind aber alle Parameter 32Bit breit (oder vielfachen davon)! Auch ein Char oder ein Word wird mit 32Bit übertragen! Zu diesem Ergebnis bin ich gekommen, weil mein Prototyp Chars enthält, und ich in LV für diesen Parameter I32 angeben kann - und umgekehrt.
Wenn man also die (gepackte) Struktur durch ihrer Elemente ersetzt, so geht das in einfacher Weise nur dann gut, wenn alle Elemente 32Bit (oder vielfaches) haben.
Was heißt das jetzt für dich?
Wenn es mit dem Ersetzen der Struktur durch ihre Elemente nicht funktioniert hat, dann gehen wir davon aus, dass die Struktur eben gepackt ist. Es muss genau die richtige Anzahl Bytes im Stack übergeben werden. Du kannst jetzt folgendes probieren: Erster Paremeter im DLL-Knoten: Bool1; Zweiter Parameter = UCHAR1+ 256*UCHAR2 + 65536*lowword(Bool2); Ditter Prameter = highword(Bool2) ...; usw; (Alle Parameter I32.) Beachte: Ich glaube du hast sieben Parameter, die zusammen unglücklicherweise kein Vielfaches von 32Bit ausmachen. Wenn du großes Glück hast, funktioniert das vielleicht. Möglicherweise musst du in diese manuelle Zusammenfassung der Werte auch noch den dritten Paramter (den Pointer) mit aufnehmen.
Wenn diese spezielle C++-Funktion aber tatsächlich eine Stackbelegung so erwartet, dass der Gesamtspeicherverbrauch über alle Parameter kein Vielfaches von 32Bit ist, dann sehe ich schwarz. Respektive kann ich dann wohl nicht mehr weiter helfen, da hier auch meine Testmöglichgkeiten beschränkt sind.
Habe ich das mit der Speicherbelegung etc. verständlich erklärt?
Ansonsten viel Erfolg mit dem DLL-Knoten!
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
|
|
|
07.05.2007, 08:54
|
Predator
LVF-Gelegenheitsschreiber
Beiträge: 62
Registriert seit: Mar 2007
8.50
2006
DE
29393
Deutschland
|
Daten einer Struktur aus LV einer DLL übergeben
war zu voreilig mit der frage bezüglich der zerlegung von words... unter datenmanipulation in LV gibt es alles was man braucht...
gruss
dennis
|
|
|
| |