Kommunikation Skripte untereinander

  • Weil du nur das eine Byte im Char-Array abfragst!
    Um den gesamten String zurückzugeben, darfst du den index nicht verwenden.
    $struct=dllstructcreate("char[100]")
    dllstructsetdata($struct,1,"Hallo AutoIt")
    $string =dllstructgetdata($struct,1)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $string = ' & $string & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    $buchstabe=dllstructgetdata($struct,1,1)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $buchstabe = ' & $buchstabe & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

  • Soweit habe ich das begriffen. Aber so wie ich das ganze Verstanden habe, kann man mit dem Index ein 1D Array erstellen.


    Weil aktuell kann ich zwar beliebig viele Spalten erstellen aber nur eine Zeile? Oder muss ich tatsächlich für jede Zeile ein neues struct erstellen?


    Ich möchte, dass meine zwei exen (Sender, Empfänger) auf ein 1D Array mit 20 Zeilen und einer 1 Spalte zurückgreifen können.


    Code
    | Zeile 0 | Spalte 0 |
    |---------|-----------|
    | [1] | 'Wert 1' |
    | [2] | 'Wert 2' |
    | [3] | 'Wert 3' |
    | [4] | 'Wert 4' |
    | [5] | 'Wert 5' |
    | ..
  • Ich bin mir nicht genau sicher, was du meinst.
    Deine "Tabelle" ist unzweifelhaft ein 2D-Array!
    Oder soll das die Entsprechung von _ArrayDisplay() sein?
    Bei der Struct ist es völlig unerheblich, in welcher Reihenfolge die Daten angeordnet sind, hauptsache DU weisst es^^. Da gibt es weder Reihen noch Spalten!


    Weil aktuell kann ich zwar beliebig viele Spalten erstellen aber nur eine Zeile? Oder muss ich tatsächlich für jede Zeile ein neues struct erstellen?

    Das verstehe ich nicht.
    Zeig doch dein Array mal. Und deine Entsprechung in einer Struct.

  • Mit einem Array welches Strings beinhalten soll ist das so eine Sache. Bei Double oder Integer weiß man ja vorab wie groß die Daten sind. Diese sind je nach Größe (byte, word, dword, qword) beschränkt. Bei Strings ist das nicht so, zwar könntest du sagen du nimmst eine Maximal zulässige Gesamtlänge der Strings, nimmt aber bei kürzeren Strings dafür schon unnötig Speicherplatz weg.


    Wenn du also sagst meine Strings bekommen einen Speicher von 64 KB (65536 Zeichen) zugewiesen, so kannst du die Strings wie in den Beispielen oben gezeigt einfach hintereinander legen. Schwieriger wird es sobald du nach Möglichkeit Platzsparend programmieren möchtest. Dann muss da was anderes her.


    Auch dafür gibt es eine Möglichkeit, aber dazu schreib ich was wenn Bedarf besteht. Die einfachste Möglichkeit: Einfach die Maximalgrenze an Zeichen festlegen, dann kannst du das Problem relativ simple Lösen:


    Global Const $iMaxLen = 1024 ; 1 Kilobyte
    Global $tStruct = DllStructCreate(_StringStruct(3 * 4, $iMaxLen))
    Global $i


    DllStructSetData($tStruct, 1, 'Account' & Chr(0)) ; [0][0]
    DllStructSetData($tStruct, 2, 'Ticket ID' & Chr(0)) ; [0][1]
    DllStructSetData($tStruct, 3, 'Vorname' & Chr(0)) ; [0][2]
    DllStructSetData($tStruct, 4, 'Nachname' & Chr(0)) ; [0][3]


    DllStructSetData($tStruct, 5, '123' & Chr(0)) ; [1][0]
    DllStructSetData($tStruct, 6, '456' & Chr(0)) ; [1][1]
    DllStructSetData($tStruct, 7, 'Max' & Chr(0)) ; [1][2]
    DllStructSetData($tStruct, 8, 'Meier' & Chr(0)) ; [1][3]


    DllStructSetData($tStruct, 9, '789' & Chr(0)) ; [2][0]
    DllStructSetData($tStruct, 10, '1011' & Chr(0)) ; [2][1]
    DllStructSetData($tStruct, 11, 'Meier' & Chr(0)) ; [2][2]
    DllStructSetData($tStruct, 12, 'Max' & Chr(0)) ; [2][3]


    Func _StringStruct($iElements, $iLen)
    Local $sRet, $i


    For $i = 1 To $iElements
    $sRet &= 'char[' & $iLen & '];'
    Next


    Return StringTrimRight($sRet, 1)
    EndFunc

  • Ok, ein Array aus Strings.
    Um die Stringlänge völlig ausser Acht zu lassen, lege ich diese einfach mal auf 20 fest.
    Das Array besteht aus 4 Spalten und 3 Zeilen, also 12 Elementen


    Schwieriger wird es sobald du nach Möglichkeit Platzsparend programmieren möchtest. Dann muss da was anderes her.


    Naja, da nimmt man eine verkettete Liste, bzw. eine einfache Liste die aus stringlen1,string1, stringlen2, string2, stringlen3, string3 ....besteht.
    Um dann den Pointer des 5. Strings innerhalb der Struct zu finden, hangelt man sich von Stringlen zu Stringlen, bis der 5. String erreicht ist.
    Oder man schreibt einfach alle Strings hintereinander und notiert sich in einer weiteren Struct (oder Array :) ) die Startpointer.
    Entspricht in etwa einer LUT (lookuptable)

  • Vielen Dank Ihr zwei...
    Dank euren Vorschlägen, habe ich nun folgende Funktion gebaut.


    Die char Anzahl bestimme ich mit StringLen ich weiß nicht ob das ganz korrekt ist aber was ich so ausprobiert habe, funktioniert es hervorragend....


    Mit dieser Funktion kann ich ein Array an eine Struct übergeben. Natürlich ist das absoluter Blödsinn, da ich direkt eine Struct erstellen kann. Aber zum lernen hat sich das gelohnt. Vielen Vielen Dank !!!


  • Schöne Funktion!
    die solltest du dahingehend erweitern, JEDEN Datentyp (String, (U)INT, FLOAT usw.) in die Struct zu bringen, damit man auch mal richtig rocken kann^^

  • Ja, jedoch ist mir beim durchschauen schon ein zwei Fehler aufgefallen ^^
    Codezeile 21 bringt's so nicht. Du nimmst ersetzt ja den ursprünglichen String ja nicht durch den Rückgabewert von StringTrimRight, jedoch ist mir aufgefallen dass ein abschließendes Semikolon bei DllStructCreate nicht schadet, aber auch keinen Effekt hast. Im Grunde hätte ich bei meinen Skript beim Return den Funktionsaufruf mir sparen können. Heißt für dich, raus damit. Desweiteren fügst du in Zeile 34 ein Chr(0) an's Stringende. Nützt dir nur nichts da du in Zeile 17 vergessen hast ein extra Byte dafür zu reservieren. Sprich: Der String wird überhaupt nicht durch ein Null Character abgeschlossen. Solltest du aber unbedingt machen! Ich verrate dir auch warum, wenn du später mal ein String veränderst im Speicher und du die Größe des eigentlichen Strings nicht kennst und n' paar Byte an Daten extra reservierst, wirst du dich wundern was für Extra Zeichen hinten am eigentlichen String in der Konsole noch mit ausgegeben werden. Ansonsten genial wie du die Funktion erweitert hast. Mach das mal noch für andere Datentypen auch noch, dann brauch ich es nämlich nicht mehr machen! xD


    Andy:

    Zitat von Andy

    [...] Naja, da nimmt man eine verkettete Liste, [...]


    Jaja, ich sagte ja nur dass es "schwieriger" sei, nicht das es schwierig ist. ^^
    Da liegen WELTEN zwischen. :D


    Im Grunde hatte ich das mit den Startpointern im Hinterkopf.
    LG :)

  • Desweiteren fügst du in Zeile 34 ein Chr(0) an's Stringende

    Was man sich sparen kann, wenn man die char-Struct um einen weiteren Char ergänzt. Dieser hat dann immer den Wert 0

  • Ok ich werde versuchen die anderen Datentypen mit zu erkennen. Eine Frage hätte ich da noch. Kann man eine bereits erstellte struct um weitere Elemente erweitern? Eine Art ArrayAdd oder redim bei einem array?


    weil dan wären Structs wirklich schöne Alternativen zu arrays, die man zudem aassoziatives Gestalten kann

  • Ja, sehr einfach^^
    Alles eine Sache der Kommunikation.
    Die Dll stellt lediglich die Menge des benutzbaren Speichers zur Verfügung, mit welchen Daten dieser Speicher genutzt wird, bestimmt der Anwender!
    Gerade bei dem Beispiel mit den Strings hatten wir schon die Listen /verketteten Listen angesprochen. Der "Sender" erstellt die Liste, der "Empfänger" klappert nun einfach die Liste so lange ab, bis das Ende erreicht ist.
    Wenn man sich nun ein Format überlegt, nach dem die Datentypen im Speicher abgelegt werden, ist es völlig unerheblich wie viele Daten im Speicher stehen.


    Wenn jetzt übrigens irgendwelche stillen Mitleser meinen, so etwas braucht doch sowieso niemand, sollten diese sich mal überlegen, woher sämtliche Datei- und Speicherdatenformate kommen! Die wachsen nämlich nicht auf Bäumen, sondern werden genau nach dem Prinzip der Weiterentwicklung nach einem bestimmten Bedarf festgelegt!
    Und ob diese "Dateien" nun auf Festplatte oder im Speicher einer Dll stehen, ist unerheblich, man kann sie auch per Mail verschicken und mit jedem anderen Programm/Betriebssystem nutzen!

  • Ok habe nun in meiner Funktion die Erkennung von Datentypen implementiert. Aktuell scheitere ich daran Uint zuerkennen, aber ansonsten läuft es ganz gut.


    Zudem habe ich die Funktion dahingehend erweitert, dass man die einzelnen Struktur Elemente mit den Array Überschriften ansprechen kann $tStruct.Account pro jeder Array Zeile erhält das Element die jeweilige Zeilennummer hintendran. Also $tStruct.Account1


    Ich überlege zur Zeit, wie ich weitere Elemente hinzufügen/ löschen und editieren kann.



    Consolen Ausgabe:

  • Sieht ja schon gut aus...


    wie man sowas wie "DllStructAddElement()" realisiert ohne die aktuelle Struct zu zerstören und eine neue mit den Daten anzulegen.

    Du denkst immer noch zu sehr an Arrays. Die Struct ist nichts weiter als ein mit irgendwelchen Daten gefüllter Bereich im RAM. Und wenn du neue Daten anhängen willst, schreib diese Daten doch einfach hinten dran.


    Aktuell scheitere ich daran Uint zuerkennen, aber ansonsten läuft es ganz gut.

    Wenn es nach mir ginge, gäbe es sowieso nur EINEN anderen Datentyp ausser String, und das wäre DWORD. Damit erschlägst du alle 32-Bit-Datentypen. Der "Empfänger" muss sowieso wissen, welchen Datentyp er aus der Struct ausliest.

  • Du denkst immer noch zu sehr an Arrays. Die Struct ist nichts weiter als ein mit irgendwelchen Daten gefüllter Bereich im RAM. Und wenn du neue Daten anhängen willst, schreib diese Daten doch einfach hinten dran.


    Genau das versteh ich nicht wie man das machen soll? Wie kann ich weitere Elemente an das DllStructCreate() dranhängen obwohl es bereits erstellt ist?

    Code
    $tStruct = DllStructCreate($sStruct)
    $tStruct = DllStructCreate($tStruct + $sStruct) ???


    Wenn es nach mir ginge, gäbe es sowieso nur EINEN anderen Datentyp ausser String, und das wäre DWORD. Damit erschlägst du alle 32-Bit-Datentypen. Der "Empfänger" muss sowieso wissen, welchen Datentyp er aus der Struct ausliest.


    Das stimmt und wäre zu dem viel einfacher, aber blockiere ich dadurch nicht enorm viel Speicher?

  • Zitat von rynow

    Das stimmt und wäre zu dem viel einfacher, aber blockiere ich dadurch nicht enorm viel Speicher?


    Wieso? Wenn du z.B. 3 Byte nur benötigst dann ist es vollkommen egal ob du 3 Bytes hintereinander nimmst oder direkt ein DWord. Und dann die 3 Bytes einfach in das DWord speicherst. Ich meine mal irgendwo gelesen zu haben dass Zugriffe im RAM in 4er Schritten (Sprich, immer 4 Bytes also ein DWord) schneller ist als ein Zugriff auf ein einzelnes Byte.


    Ob nun 1 bis 3 Byte an Speicher nun übrig bleibt ist total irrelevant. Das juckt keine Sau, bei 8 Gigabyte an Arbeitsspeicher kannst du schon einen String mit 8'796'093'022'208 Zeichen abspeichern. Und wenn du mir einen Text liefert der mein RAM sprengt, dann schicke ich dir gerne die Zahl in Euros zu. ^^


    Selbst wenn du jedes Zeichen eines 1'000'000 Zeichen langen Textes in ein DWord packst, verschwendest du gerade mal 0.000000341% des Arbeitsspeicher. Also, dass du "enorm" viel Speicher blockierst ist totaler Schwachsinn. Wenn du mir nicht glaubst, rechne nochmal selber nach. Also mach dir mal da keine Gedanken zu.




    Zitat von rynow

    Genau das versteh ich nicht wie man das machen soll? Wie kann ich weitere Elemente an das DllStructCreate() dranhängen obwohl es bereits erstellt ist?


    Da du hier speziell nach DLLStruct fragst, entweder erstellst du die Struktur komplett neu + die dranzuhängenden Daten, oder du reservierst dir ein extra DWord und schreibst da einfach den Pointer zu einer neuen Struktur hinein, welche die erweiterten Daten enthält. Andy sagte es ja bereits: "Verkettete Liste"


    Für die DLL muss ich denke ich nichts zu sagen, da kannst du ja selber locker an jeder x-Beliebigen Stelle die Daten verändern und somit auch erweitern.

  • Genau das versteh ich nicht wie man das machen soll? Wie kann ich weitere Elemente an das DllStructCreate() dranhängen obwohl es bereits erstellt ist?

    Mal angenommen, du hast 1 kB an Speicher reserviert. Deine bisherige Struct ist 200 Byte groß, folglich hast du noch 800 Byte an "Platz" zur Verfügung. Diesen "Platz" kannst du nach Belieben beschreiben. Da du ja beim DllStructCreate() auch einen Pointer angeben kannst, kannst du diesen Bereich innerhalb der 800 Bytes sogar an irgendwelche esoterischen Positionen setzen.


    Weiterhin "überschreibst" du mit einem Dllstructcreate() NICHTS! Gerade im Gegenteil, du erstellst lediglich ein "Fenster" bestimmter Größe, welches du mit Hilfe des Pointers an eine beliebige Position im Speicher setzen kannst.