Kommunikation Skripte untereinander

  • Die DLL an sich wird imho total einfach, es wird nur ein Speicherbereich von 1MB reserviert.
    Der Aufruf der Funktion gibt einfach nur einen Pointer auf eben diesen Speicherbereich zurück.
    In diesen Speicher kann nun jedes Programm beliebig Daten einschreiben bzw. auslesen. So die Theorie^^
    Naja, vielleicht mache ich sogar 2 Funktionen, eine zum Schreiben, die andere zum Lesen. Usability ftw! Ich setz mich mal dran....


    //EDIT
    naja, fast hätte ich es mir gedacht, klappt so nicht.
    Man kann nicht von "außerhalb" auf innerhalb der DLL reservierten Speicher zugreifen.
    Hab eine dll erstellt

    welche auch einwandfrei funktioniert, sie gibt den Pointer auf die Variable _mem zurück.
    Allerdings kann man per dllstructcreate(byte[1000],$pointer) nicht auf diesen Speicher zugreifen. ;(


    Umgekehrt funktionierts aber, man könnte der DLL einen Wert übergeben welcher im Speicher der DLL abgelegt wird, die Frage ist, ob von einem 2. Script dieser Speicher gelesen werden kann!


    DLL dazu


    In einem Script( compiliert) gestartet, funktioniert das einwandfrei. Man kann dieses Script laufen lassen und ein weiteres starten, in dem die Zeile mit dem VarIN-Call auskommentiert ist.
    Leider wird, wenn man die DLL aus einem weiteren Script anspricht, der Speicher nicht Global angesprochen...werde da wohl nochmal etwas nachhaken müssen! 8)
    Funzt nicht...Speicher innerhalb der DLL wird geschützt. Um da ranzukommen, verwendet man die Methode per _WinAPI_ReadProcessMemory(), das geht aber einfacher, s.o.

  • Achso, ich ging davon aus das es möglich sein sollte den speicherplatz dynamisch anzufordern. Das wäre natûrlich eine herausforderung. Aber wenn du sagst "so viel speicher wird bereitgestellt und nicht mehr" dann sollte das einfacher sein. Naja, in den meisten fällen ist 1 MB schon mehr als genug. Bin mal gespannt was dabei herum kommt. Stellst du dann auch den sourcecode der dll zur verfügung?

  • s. EDIT...so ist das, wenn man Threads schreibt/editiert, und erst nach Stunden auf den "abschicken" Button drückt^^

  • Andy, du musst die Datensektion noch mit shareable global verfügbar machen:

    Code
    section '.data' data readable writable shareable


    So funktioniert das dann auch.

  • Hallo Zusammen,


    Oscar: Auch dir vielen Dank für die angezeigte Möglichkeit.


    @Make-Grafik:

    Zitat

    Also, du hast nun einen Eimer voll an Möglichkeiten von uns bekommen...

    Das ist wohl war und ich bin sehr dankbar dafür. Ich versuche halt eine möglichst elegante und "flüchtige" Kommunikation zu finden.



    Andy:


    Zitat

    ...habe mir das mit der DLL durch den Kopf gehen lassen.
    Vorteil wäre, beliebig viele Programme auf ein und denselben Speicherbereich zugreifen lassen zu können...
    Sozusagen eine universell verwendbare Dll zum beliebigen Datenaustausch.
    Bald ist ja Wochenende 8).

    ...über die Umsetzung dieser Idee, wäre wohl nicht nur ich sehr sehr Dankbar! Eine Kommunikation (flüchtiger Speicher) von mehreren Skripten ist einer der größten Funktionen die ich bzw. auch einige andere Personen bei AutoIt vermissen.


    Vielen Dank für eure Zahlreiche Anteilnahme an diesem Thread!


    Gruß
    Homer J. S.

    ...wenn die Donuts auch nur halb so gut schmecken wie sie aussehen, dann sehen sie doppelt so gut aus wie sie schmecken...

    Einmal editiert, zuletzt von Homer J. S. ()

  • Basierend auf Andy's Assemblercode habe ich selber nun eine kleine einfache DLL geschrieben. In ihr werden 10 Byte an Speicher reserviert (Für eine einfache 10 Zeichen lange Nachricht). Mit der Funktion „GetPtr“ kann der Pointer für den Speicher gelesen werden. Mithilfe einer Struktur lässt sich dies in AutoIt nun ganz simple ansprechen. Der Pointer des Speicherbereiches wird einfach an die Strukur übergeben.


    Im Anhang befindet sich ein Beispielskript sowie die nötige DLL + Quelltext. Das Beispielskript ruft sich selber nochmals über den Interpreter auf. Beim ersten Aufruf wird die Nachricht in den Speicherbereich geschrieben, beim zweiten Aufruf in einer MessageBox ausgegeben. Danach geschieht das Selbe nur in anderer Richtung. Das soll verdeutlichen das wirklich nur ein Speicherbereich genutzt wird. Man kann also von mehreren Prozessen problemlos darauf zugreifen.


    Andy:
    Gute Arbeit von dir, ich habe lediglich ein wenig (oder fast alles :x) bei dir abgeguckt und die kleine Sache mit „shareable“ eingepflanzt. Ziemlich interessant was so alles möglich ist. Die Lorbeeren gehören dir xD

  • Sodele, habe mal ein Beispielscript erstellt.


    Die EXE mehrfach starten, es wird je gestarteter GUI ein Zähler hochgezählt.
    Diesen Zähler kann man beliebig lange "anhalten", indem man den Rahmen der GUI anfasst.
    Jede dieser GUI´s lädt die DLL. Diese wird im Speicher natürlich nur einmal erstellt ! Das ist der Sinn einer Dynamic Link Library :D
    Die GUI´s erhalten von dieser DLL nur den Pointer auf den innerhalb der DLL verwendeten Speicherbereich.
    Dieser Speicherbereich kann nun von JEDER GUI beliebig gelesen/beschrieben werden.
    Dazu wird an der Position dieses Pointers eine beliebige Struct erstellt. Ich habe einen String erstellt, und auch einen INT, welcher als Reset-Flag dient, um die GUI´s zu synchronisieren.


    Klickt man nun in einer BELIEBIGEN GUI auf den "Reset/Sync"-Button, wird aus dieser GUI im Speicher der DLL das Reset-Flag gesetzt.
    Da alle GUI´s permanent den Status des Reset-Flags im Speicher der DLL abfragen, wird im Falle eines Resets IN JEDER DER GUI´s darauf reagiert und der Zähler auf Null gesetzt.


    Interprozesskommunikation! :D


    Eins ist noch interessant, wenn man den Speicherbereich innerhalb der DLL vergößert, findet irgendwann Avira Antivir in der DLL den Packer.GEN :rofl: Wie gesagt, ab einer betimmten Anzahl Nullen in der Datei werden von den Scannern Viren gefunden, weiß jemand den Grund?


    autoit.de/wcf/attachment/24801/


    //EDIT
    Man sollte noch erwähnen, dass die DLL nichts weiter macht, als einen Speicherbereich zu reservieren. Sämtliche Aufteilungen bzw. Strukturen finden alleine im AutoIt-Script statt. So kann man nun Texte, oder Variablen oder Bilder oder wasauchimmer an andere Programme übergeben.


    //EDIT2
    Script um das "Reset" deutlicher zu machen, compilieren, mehrfach starten...

  • Die EXE mehrfach starten, es wird je gestarteter GUI ein Zähler hochgezählt.
    Jede dieser GUI´s lädt die DLL. Diese wird im Speicher natürlich nur einmal erstellt ! Das ist der Sinn einer Dynamic Link Library :D


    Sicher? Ich hatte mich schon die ganze Zeit gefragt, wie eure Idee überhaupt funktionieren kann, aber wahrscheinlich liegt es einfach nur an dem "shareable," das MG in #24 erwähnt hat.
    Microsoft sagt dazu nämlich folgendes:

    Every process that loads the DLL maps it into its virtual address space.
    After the process loads the DLL into its virtual address, it can call the exported DLL functions.


    Und damit mein Post nicht völlig umsonst war hier noch eine Möglichkeit, die noch nicht (direkt) erwähnt wurde: Pipeline DLL - die einfachste Art der Prozess-Kommunikation

  • James,
    genau aufgrund der von dir geposteten Microsoft-Statements zum Thema bin ich überzeugt, dass diese "sharable"-Geschichte überhaupt nicht im Sinne des Erfinders (bzw. der "neueren" BS) ist!
    In sämtlichen von mir gelesenen Forenbeiträgen taucht irgendwann ein Microsoft-MVP auf und bestreitet vehement die von uns gezeigten Möglichkeiten.
    Die innerhalb der DLL untergebrachten Funktionen werden natürlich nur einmal in den Speicher geladen, genau dafür ist das System DLL/LIB ja gemacht! Es gibt Konstruktionen, sogar mit mehreren Threads innerhalb eines Prozesses "eine" Funktion im Speicher zu benutzen. Alles andere wäre auch unsinnig. Sämtliche Betriebssystem-eigenen DLL´s stellen ihre Funktionen ja auch sämtlichen Programmen zur Verfügung.


    Hat ggf. ein C/C++-Spezi eine Möglichkeit, diese "shareability" von Speicher innerhalb mit einem Compiler erstellten DLL nachzuvollziehen?


    //EDIT
    Mit dieser Methode kann man übrigens ECHTES Multitasking (eher Multiprocessing) realisieren!
    Statt in einem Prozess mehrere Threads zu erstellen, erstellt man einfach mehrere Prozesse!
    Windows sorgt selbstständig dafür, dass verfügbare Prozessorkerne ausgelastet werden. 8o

  • Hallo zusammen,


    jetzt hätte ich noch eine Frage an Andy.


    wie kann man aus dem asm Code eine dll erstellen
    und wie könnte man den Speicherbereich der reserviert werden soll durch den DLLCall direkt angeben.
    Im Moment ist der Speicherbereich ja begrenzt auf 10KB.


    Grüße
    Schnuffel

    MfG Schnuffel


    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

  • Der asm code muss mit der FASM.exe (flat assembler -> http://www.flatassembler.net) kompiliert werden. Der benötigte speicherbereich MUSS vor dem kompilieren angegeben werden, das spãter dynamisch zu machen ist so leider nicht möglich. Reserviere dir also genug speicher.


    Ich arbeite aber gerade an einem tool der solch eine dll erstellt. Schließlich hat nicht jeder asm erfahrung oder lust das selber zu kompilieren. Das tool wird dann in autoit geschrieben sein, wird aber noch ein bisschen dauern bis es fertig ist. So hat dann jeder die möglichkeit diese art der kommunikation zu nutzen.

  • Schnuffel, Einfach den Code in FASMW.exe (der Editor) laden und Ctrl-F9 (Compile) drücken, dann ist die DLL erstellt.
    Dynamisch den Speicherbereich zu erstellen geht auch, dazu ruft man einfach ein MemAlloc() auf ^^
    Aber das könnte man auch direkt aus dem AutoItcode machen, somit wäre das ganze witzlos.
    Ich würde einfach einige DLL´s unterschiedlicher Größe erstellen und mit eigenen Namen versehen.
    MemShare_1kb.dll
    MemShare_100kb.dll
    MemShare_1Mb.dll
    MemShare_100Mb.dll
    usw.
    Da die reservierte Speichergröße heutzutage kein Thema sein sollte, nimmt man die DLL, welche für das Vorhaben reichlich Platz bietet.
    Selbst wenn man in der Anwendung nur 10% des Speicherplatzes in der DLL benötigt....who cares :D



    @MG, sollte so schwer nicht sein, der eigentliche DLL-Code bleibt ja konstant, nur die Größe der Variablen im Datasegment ändert sich. Und Nullen reinpacken sollte so schwer ja nicht sein.

  • Jetzt wo du's sagst, auf das mit MemAlloc bin ich nicht gekommen. Prinzipiell könnte man so 4 byte in der dll reservieren und dort den pointer zu den per MemAlloc reservierten speicher hinein schreiben. So hätte jeder prozess direkt den passenden pointer und man kann locker den speicher dynamisch verändern. Ob das aber dann immernoch so einfach via dllstruct funktioniert, müsste man mal ausprobieren.


    €dit: {
    Hab's ausprobiert, der reservierte speicher via GlobalAlloc sowie VirtualAlloc wollen zum erbrechen nicht mit dllstruct's angesprochen werden. Auch nicht wenn man den speicher direkt in der dll anforder. Hab sogar aus verzweiflung versucht die prozedur welche den speicher anfordert auch mit shareable zu kennzeichnen. Nützt nichts, aber ich hab's mir sowieso schon gedacht. Naja ^^
    }


    Und das mit dem tool hätte sich dann so auch erledigt, da ja dann nur eine einzige dll mit 4 byte reservierten speicher erforderlich ist. Aber ansonst: paar nullen mehr hinein schreiben (wie du's so schön gesagt hast). Aber trzd. muss man dann den header noch anpassen (wenn ich mich richtig errinnere), sollte aber so gehen.


    Achja, mich würde das schon interessieren wenn man 10 mb an daten reserviert aber nur 1 mb nutzt. Bei meiner download geschwindigkeit bin ich froh wenn entwickler bytesparend programmieren würden. xD


    [Kann es sein dass wir solangsam vom eigentlichen thema abschweifen?]

  • Danke Euch.


    Andy das mit der FASM werd ich ausprobieren.


    Ich hab die dll dann sowieso als Variable in autoit eingebettet und passend zur Anforderung erstellt und gestartet.

    MfG Schnuffel


    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

  • @MG, hast du virtualalloc mit MEM_COMMIT | MEM_RESERVE mal getestet? WENN ich so Speicher reserviere, hau ich als protect-Parameter auch gleich PAGE_EXECUTE_READWRITE rein 8o


    Schnuffel bin schon auf Anwendungen gespannt!

  • Andy: Vielen vielen Dank für deine geniale Idee/Arbeit! Die Kommunikation funktioniert tadellos :thumbsup: . Allerdings habe ich noch ein paar Fragen...



    1 - Ich kann das Beipiel Skript nicht mit 64Bit laufen lassen, da folgender Fehler entsteht:


    ...\Desktop\sharedmem\sharedmemdll.au3 (19) : ==> Subscript used with non-Array variable.:
    $struct = DllStructCreate("char[8];int", $ptr[0])
    $struct = DllStructCreate("char[8];int", $ptr^ ERROR


    Darauf habe ich versucht mit "flat assembler" und der folgenden Änderungen...
    include 'win32ax.inc' ==> include 'win64ax.inc'
    ...eine neue "*.dll" zu erstellen, leider mit den Fehlermeldungen:


    Instruction:
    push rbp


    Source:
    proc64.inc [308]
    proc64.inc [308]
    proc64.inc [355]
    proc64.inc [355]
    proc64.inc [317]


    Gibt es eine Möglichkeit die "*.dll" 64Bit kompatibel zu erstellen?



    2 - Wie erweitere ich den Speicher z.B. auf 500Kbyte? Im ASM-Code steht folgendes:


    _mem dd 1000 dup 0 ;10 Kb Speicher


    entspricht dann


    _mem dd 50000 dup 0 ;500 Kb Speicher


    den 500Kbyte? Ich verstehe die Umrechnung nicht ganz ?(



    @Make-Grafik: Ich möchte mich auch bei dir für deine Hilfe und Unterstützung bedanken!



    Gruß
    Homer J. S.

    ...wenn die Donuts auch nur halb so gut schmecken wie sie aussehen, dann sehen sie doppelt so gut aus wie sie schmecken...

  • @Homer j.S.,


    zu 2, das war ein kurzfristiger "Fehler" von mir, da bei mir der Virenscanner gesponnen hat, wenn ich innerhalb der DLL mehr als 6k Speicher reserviert habe.
    Ursprünglich stand dort _mem dd 10000 dup 0 ;10 Kb Speicher
    Jetzt alles klar? 8)


    zu 1, habe mit FASM noch keine 64Bit-DLL assembliert, werde mich mal dransetzen.

  • jetzt ist mir in FASM aufgefallen, die erstellte dll ist immer knapp 4x so groß wie der allozierte Speicher.
    Das ist doch nicht im Sinne des Erfinders???
    Ich dachte damit wird "nur" Speicher im RAM angefordert und reserviert.
    Aber in der dll???


    Mache ich etwas falsch?


    Beispiel einer 1MB dll:

    MfG Schnuffel


    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

  • 64-Bit dll


    und Script dazu^^


    Schnuffel
    schau mal nach, was dd bedeutet ;-)
    um bytes zu reservieren, _mem db 10000 dup 0 ;10 Kb Speicher
    um words zu reservieren, _mem dw 10000 dup 0 ;20 Kb Speicher
    um dwords zu reservieren, _mem dd 10000 dup 0 ;40 Kb Speicher
    um quadwords zu reservieren, _mem dq 10000 dup 0 ;80 Kb Speicher


    http://flatassembler.net/docs.php?article=manual#1.2.2