[Tutorial] DLL's in C für AutoIt

  • Herzlich Willkommen zum "DLL's ins C für AutoIt!" Tutorial

    Wie man eventuell schon im Titel ablesen kann, geht es in diesem Tutorial um DLL und AutoIt.
    Ich weiß das dass Thema schon mehrere male durchgekaut wurde, aber Ich hab mal vor das alles an einer Zentralen Stelle zu listen.

    Als erstes sei gesagt, eine DLL zu erstellen ist nicht wirklich schwer, Es kommt nur auf die Herangehensweise an.

    Für das Tutorial werden folgende Tools / Programme vorrausgesetzt:

    • TCC (Tiny C Compiler, als Alternative zu Visual Studio C++) [281 KB]
    • Eine IDE bzw ein Programm was für C geeignet ist (in meinem Fall Sublime Text 2 oder halt Notepad++)

    Und schon kann es losgehen:

    • Wechselt in das Verzeichnis wo ihr TCC heruntergeladen habt.
    • Entpackt das ZIP-Paket.
    • Wechselt ins entpackte Verzeichnis (und in den Ordner tcc\)
    • Erstellt (der Übersicht halber) einen neuen Ordner (meinetwegen DLLTUT\)
    • Geht in diesen Ordner und erstellt mir eurem Editor eine Datei mit dem Typ *.c (zb. Dll.c)
    • Öffnet die Datei mit eurem Editor

    Jetzt gehts ans Eingemachte:


    Ich schreibe euch der Vollständigkeit erstmal den vollen Quellcode hin und erkläre dann bestimme Parts von ihm direkt danach)

    Code
    #include <windows.h>
    
    
    #define AUTOIT_CC __declspec(dllexport)
    
    
    AUTOIT_CC int Add(int Num1, int Num2)
    {
    	return (Num1 + Num2);
    }


    Also, fangen wir mal an:

    Code
    #include <windows.h>


    Bindet die notwendigen Header als Include in unser Script ein.
    Header beschreiben in C/C++ meistens, wie Funktionen definiert sind (von den Typen her, etc).

    Code
    #define AUTOIT_CC __declspec(dllexport)


    Definiert die Konstante AUTOIT_CC mit der genutzten Aufrufkonvention.
    Der Name der Konstante kann frei wählbar sein (in dem Fall bedeutet es einfach AutoIt Calling Convetion).

    Code
    AUTOIT_CC void Add(int Num1, int Num2)


    Erstellt eine Funktion (die via der ermittelten Aufruf Konvention) aufgerufen wird
    In dem Fall rechnet die Funktion die 2 übergebenen Zahlen (vom Typ int) zusammen und gibt sie zurück (als Zahl vom Typ int).

    Code
    return (Num1 + Num2)


    Sollte sich selbst erklären.

    Kompilieren der Dll
    Nun kommen wir zum richtig interessantem Teil, das Kompilieren der Dll :)

    Code
    tcc -shared tcc\dll.c -o DLLTUT\Dll.dll


    Der Befehl kompiliert die DLL (da Parameter -shared) in unser Verzeichnis als Dll.dll
    Das wars schon, die DLL ist fertig

    Aufruf durch AutoIt

    [autoit]


    #AutoIt3Wrapper_UseX64=n

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

    $iNumber1 = 17
    $iNumber2 = 34

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

    $aReturn = DllCall(@ScriptDir & "\Dll.dll", "int:cdecl", "Add", "int", $iNumber1, "int", $iNumber2)
    If @error Then Exit MsgBox(16, "Fehler", "DllCall Fehler: " & @error)

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

    MsgBox(64, "Ergebnis", $aReturn[0])

    [/autoit]

    Das wars.
    Wir sind komplett Fertig.

    Nun habt ihr eine Grundlage für eure DLL's.

    PS: Ich sehs schon kommen, der Ansturm von den ganzen DLL's :D

  • Danke für das Tutorial! Ich nehme normalerweise immer MinGW, da es universeller einsetzbar ist, aber für einfache Sachen ist TCC ideal und die Dateigröße ist bei TCC auch super, nur 1.50 kB für diese DLL.


    Edit: Hier noch ein Hilfsprogramm, das ich mal zum Kompilieren verwendet habe. Einfach Pfade anpassen.

    Spoiler anzeigen
    [autoit]

    If $CmdLine[0] = 0 Then Exit
    Local $Exe, $PID
    Local $Path = StringLeft($CmdLine[1], StringInStr($CmdLine[1], "\", 0, -1) - 1)

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

    If MsgBox(36, "DLL file?", "Compile the code to DLL file?") = 6 Then
    $Exe = StringLeft($CmdLine[1], StringInStr($CmdLine[1], ".", 0, -1) - 1) & ".dll"
    $PID = Run('C:\tcc\tcc.exe -shared "' & $CmdLine[1] & '" -o "' & $Exe & '"', $Path, @SW_HIDE, 0x2 + 0x4)
    Else
    $Exe = StringLeft($CmdLine[1], StringInStr($CmdLine[1], ".", 0, -1) - 1) & ".exe"
    $PID = Run('C:\tcc\tcc.exe "' & $CmdLine[1] & '" -ltcc1 C:/tcc/lib/user32.def -o "' & $Exe & '"', $Path, @SW_HIDE, 0x2 + 0x4)
    EndIf

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

    Local $sOutput
    While 1
    $sOutput &= StdoutRead($PID)
    If @error Then ExitLoop
    WEnd
    While 1
    $sOutput &= StderrRead($PID)
    If @error Then ExitLoop
    WEnd

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

    MsgBox(0, "TCC Output", $sOutput)

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