Dll erstellen und mit AutoIt nutzen - FreeBasic Tutorial

  • Kriegt man damit auch eine *dll hin die man in ein Prozess injiziert, weil eine Uhr zum zocken im Vollbildmodus wäre nicht schlecht. Bevor ich mich weiter mit C++ abstrampel würde ich dann lieber von 0 anfangen und FreeBasic lernen. :)

    Mit freundlichen Grüßen

    volle

  • Kriegt man damit auch eine *dll hin die man in ein Prozess injiziert, weil eine Uhr zum zocken im Vollbildmodus wäre nicht schlecht. Bevor ich mich weiter mit C++ abstrampel würde ich dann lieber von 0 anfangen und FreeBasic lernen. :)


    Kleb dir eine kleine LCD-Uhr oben auf den Bildschirm. Wozu brauchst du da DLL-Injection?
    z.B. So was

  • Bilanz:
    Montag - Freitag: Überlegung ob sich der Aufwand lohnt.
    Samstag - FB Referenz (deutsch) gelesen.
    Sonntag - Lesen, Lesen, Lesen und ... erste primitive DLL geht vom Band.
    Montag - Lesen + Beginn an einem kleinen Konsolenspiel (wie nennt man sowas ? Text basierte DOS Spiele^^)
    Dienstag - Konsolenspiel weiterentwickeln
    Mittwoch - keine Zeit
    Donnerstag - Überlegung ob die Kugelgeschichte mit akzeptabelem Aufwand in FB machbar ist.
    Freitag (heute) - nach 3 interessanten Stunden voller glücklicher Erlebnisse läufts :thumbup:

    Fazit:
    FB ist sehr schnell in relativ großem Umfang lernbar und Anwendbar.
    Man muss seine Skripte etwas anpassen um die Kompatibilität zu erhöhen.
    FB gibt relativ selten viele Errors aus. Selbst wenn man mal Klammern vergisst kommt nur eine Warnung. Das Programm läuft idr trotzdem
    Print ist in Dlls kompatibel mit der Konsole in SciTE. Zum Fehlersuchen optimal.
    Die Ausführungsgeschwindigkeit liegt selbst bei blutigen Basic Anfängern wie mir sehr weit über AutoIt.

    Danke für das Tut. Auch wenn es nur der Schubs war, nun rollt alles :)

  • Klasse Implementierung Mars! :thumbup:

    Jetzt könnte man die DLL noch einbetten und direkt vom Speicher aufrufen, so dass das Mitgeben der DLL unnötig wird.

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Hab gleich mal eine Frage:

    Wie kann man denn einen selbst definierten type in der erstellten DLL nutzen.
    Dieser soll als Rückgabewert einer Funktion in Autoit nutzbar sein.

    Hab da nämlich versucht die komplexen Zahlen und ihre Rechenregeln in eien DLL zu packen, allerdings komme ich mit den Rückgabewerten nicht klar?!?

    der Strahleman 8)

    Wenn denn alles so einfach wäre wie

    [autoit]

    "Autoit"

    [/autoit]

    meine UDFs
    Math2

    Wichtige Threads
    Math2

  • Alles was nicht dem Standard entspricht, muss in AutoIt ein Pointer zu einer DLLStruct sein. Am besten ist dann aber auch nicht direkt den Rückgabewert zu verwenden, sondern z.B. den ersten oder letzten Parameter ByRef zu übergeben. Dann hast du auch keine Probleme mit dem 'wer allokiert den Speicher und wer gibt ihn wieder frei'.

  • Danke funkey,

    habs jetzt hinbekommen, dass über ByRef die ermittelte Struktur an Autoit übergeben wird. Aber kann ich auch diese erstellten Strukturen wieder von Autoit an die DLL zur Weiterverarbeitung zurückübergeben und eine neu berechnete Struktur dann von der DLL erhalten?

    Wenn denn alles so einfach wäre wie

    [autoit]

    "Autoit"

    [/autoit]

    meine UDFs
    Math2

    Wichtige Threads
    Math2

  • Zitat von Strahleman


    habs jetzt hinbekommen, dass über ByRef die ermittelte Struktur an Autoit übergeben wird. Aber kann ich auch diese erstellten Strukturen wieder von Autoit an die DLL zur Weiterverarbeitung zurückübergeben und eine neu berechnete Struktur dann von der DLL erhalten?

    Natürlich kann man das. Einfach Struktur erstellen (DllStructCreate) und den Pointer der Funktion übergeben (DllStructGetPtr).
    Und wenn du von einer Funktion einen Pointer erhältst, dann kannst du diesen auch gleich direkt der nächsten Funktion übergeben.

  • Hallo,

    und nochmal ich.
    Jetzt klappt es. Hab ein ByRef in einer Funktion vergessen.
    Merkwürdigerweise funktioniert die Rückübergabe bei allen erstellten einparametrigen Type-Varianten (inkl. Double) und bei allen mehrparametrigen Type-Varianten wenn kein Double verwendet wird.
    Allerdings würde ich gerne mit einem vier-parametrigen Type aus Double arbeiten.

    Hiermal der Beispiel-Code.
    Der Aufruf in Autoit:

    Spoiler anzeigen
    [autoit]


    $hDll = DllOpen($strdll)

    [/autoit] [autoit][/autoit] [autoit]

    $a = DllStructCreate("double;double;double;double")
    $ptrA = DllStructGetPtr($a)
    $arrPtrA = DllCall($hDll, "Ptr", "f_inTest", "double", 1,"double", 2,"double", 3,"double", 4, "ptr", $ptrA)

    [/autoit] [autoit][/autoit] [autoit]

    $b = DllStructCreate("double;double;double;double")
    $ptrB = DllStructGetPtr($b)
    $arrPtrB = DllCall($hDll, "Ptr", "f_Test", "ptr", $ptrA, "ptr", $ptrB)

    [/autoit] [autoit][/autoit] [autoit]

    DllClose($hDll)

    [/autoit]


    Die entsprechende DLL:

    Spoiler anzeigen

    Wie gesagt, wenn ich beispielsweise vier byte-Typen verwende funktioniert diese Variante, nur eben nicht bei der Version wie oben mit den Double-Typen ?!? ?(
    Ich hoffe jemand kann mir auf die Sprünge helfen!

    Wenn denn alles so einfach wäre wie

    [autoit]

    "Autoit"

    [/autoit]

    meine UDFs
    Math2

    Wichtige Threads
    Math2

  • Ich hätte das so gemacht:

    AutoIt
    [autoit]

    Global $strdll = "Freebasic_DLL.dll"

    [/autoit] [autoit][/autoit] [autoit]

    $hDll = DllOpen($strdll)

    [/autoit] [autoit][/autoit] [autoit]

    $a = DllStructCreate("double;double;double;double")

    [/autoit] [autoit][/autoit] [autoit]

    $ptrA = DllStructGetPtr($a)
    $aRet= DllCall($hDll, "none", "f_inTest", "double", 1,"double", 2,"double", 3,"double", 4, "ptr", $ptrA)

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite(DllStructGetData($a, 1) & @CRLF)
    ConsoleWrite(DllStructGetData($a, 2) & @CRLF)
    ConsoleWrite(DllStructGetData($a, 3) & @CRLF)
    ConsoleWrite(DllStructGetData($a, 4) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    $b = DllStructCreate("double;double;double;double")
    $ptrB = DllStructGetPtr($b)
    $arrPtrB = DllCall($hDll, "none", "f_Test", "ptr", $ptrA, "ptr", $ptrB)

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite(DllStructGetData($b, 1) & @CRLF)
    ConsoleWrite(DllStructGetData($b, 2) & @CRLF)
    ConsoleWrite(DllStructGetData($b, 3) & @CRLF)
    ConsoleWrite(DllStructGetData($b, 4) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    DllClose($hDll)

    [/autoit]
    Freebasic_DLL
  • Das das so funktioniert, hab ich gar nicht gewusst ;)

    Dennoch ist es einfacher ohne ByRef zu arbeiten und in FB die Pointerschreibweise zu benutzen, dann behält man besser den Überblick - zumindest ich

  • In AutoIt geht es übrigens auch so:

    [autoit]


    $a = DllStructCreate("double;double;double;double")

    [/autoit][autoit][/autoit][autoit]

    $aRet= DllCall($hDll, "none", "f_inTest", "double", 1,"double", 2,"double", 3,"double", 4, "struct*", $a)

    [/autoit]