C#-DLL in AutoIt einbinden

  • Hallo!

    Ich habe mir soeben eine eigene dll erstellt mit dem namen "testdll.dll" der source ist folgender:

    Spoiler anzeigen

    Ich will diese dll nun mit autoit aufrufen und verwenden. Meine dll müsste den wert 10 als "long" zurückgeben, allerdings bekomme ich nur 0 in der msgbox angezeigt?
    Ich habe bereits in der Hilfe datei geschaut und die dll kann ich auch in einem anderen csharp projekt erfolgreich einbinden aber wieso funzt das nicht in autoit?

    Spoiler anzeigen
    [autoit]


    $dll = DllOpen("testdll.dll") ;ist im windows ordner drin
    $aRes = DllCall ($dll, 'long', 'Rechnen')

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

    MsgBox(0,"",$aRes)

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

    Einmal editiert, zuletzt von I3iLLiG (24. November 2009 um 16:22)

  • habe bereits versucht die rückgabe als array anzuzeige, allerdings kommt bei mir ein compile error - dass der rückgabe wert kein array ist...

    aber wieso sollte es nicht möglich sein eine c# dll in autoit zu öffnen? ;(

    Code
    4) : ==> Subscript used with non-Array variable.:
    MsgBox(0,"",$aRes[0])
    MsgBox(0,"",$aRes^ ERROR
  • Du kannst die DLL in C++ übersetzen oder vielleicht kannst du .NET irgendwo unter Projekt-Einstellungen deaktivieren. :) *Bin mir nicht mehr sicher.. ^^*
    Sonst gibts noch Sprachen wie Purebasic, um leicht DLL's zu erstellen. Die Programmiersprache ist sehr leicht. Kostet leider.

  • Hallo RAPTOR-ONE,

    das hört sich ja super an!
    Allerdings hab ich noch nicht so ganz verstanden wie, das alles abläuft im Moment hab ich folgend(e)n Befehl ausgeführt:

    Code
    "C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe" "C:\Users\hamann\Desktop\testdll.dll"
    "C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe" "C:\Users\hamann\Desktop\testdll.dll" /regfile:testdll.reg
    "C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe" "C:\Users\hamann\Desktop\testdll.dll" /tlb:testdll.tlb
    pause
    Spoiler anzeigen

    danach habe ich den Oberen autotiscript gestartet, allerdings bekomme ich wieder 0 als rückgabewert.
    (array[0] liefert einen compile error)

    kannst du mir ein stoss in die richtige richtung geben? 1000 dank

    i3illig

    edit: ich habe jetzt [assembly: ComVisible(true)] auf true gesetzt und die Befehle wurden alle erfolgreich ausgeführt, allerdings bekomme ihc noch immer eine 0 zurück :(

    Einmal editiert, zuletzt von I3iLLiG (26. August 2009 um 22:33)

  • Welche Antwort meinst du?
    Deepred hat schon gesagt, es ist nicht möglich, eine .NET basierende DLL zu verwenden.
    Registrieren einer DLL ändert nichts daran oder doch? :cursing:

  • Zitat


    Sobald eine Klasse registriert ist, kann diese von jedem COM-Client wie eine COM-Klasse verwendet werden.

    ist autoit ein comclient?

  • Hi,
    ich hab jetzt eine noch einfachere Lösung gefunden.

    1. C# -Dll erstellen
    2. Dll mit ildasm dekompilieren
    3. MSIL-Code Modifizieren
    4. MSIL-Code wieder zu einer Dll kompilieren

    Beispiel:
    Funktionen die exportiert werden sollen müssen static definiert sein.
    C# Code

    Spoiler anzeigen


    Der Code wird mit folgendem Befehl kompilieren.

    Code
    Csc.exe /OUT:AutoIT3CSharpDll.dll /target:library AutoIT3CSharpDll.cs


    Nach erfolgreichem kompilieren wird die Dll dekompiliert.

    Code
    ildasm.exe /OUT:AutoIT3CSharpDll.il AutoIT3CSharpDll.dll


    Es muss in der AutoIT3CSharpDll.il nun folgender Befehl gesucht werden.

    Code
    .corflags 0x00000001


    Das Flag muss auf 0x00000002 verändert werden.
    Direkt darunter können folgende Zeilen eingefügt werden.

    Code
    .vtfixup [1] int32 fromunmanaged at VT_01
    .data VT_01 = int32(0) 
    
    
    .vtfixup [1] int32 fromunmanaged at VT_02
    .data VT_02 = int32(0) 
    
    
    .vtfixup [1] int32 fromunmanaged at VT_03
    .data VT_03 = int32(0)


    vtfixup ist eine Tabelle mit einem Eintrag ([1]). Int32 gibt an das jeder Eintrag 32Bit groß ist und fromunmanaged gibt an das die Funktion auch von Unmanaged Code aufgerufen werden kann.
    .data erstellt die Variable und initialisiert sie mit 0.
    Es werden in diesem Beispiel 3 Tabellen erstellt (VT_01, VT_02, VT_03), weil drei Methoden exportiert werden sollen.

    Code
    .vtentry TBLNUM : 1
    .export [ORDINALNUM] as NAME


    Diese beiden Befehle müssen jeweils bei den Methoden eingefügt werden. TBLNUM ist ein Integer Wert der die Tabelle angibt (erster Aufruf von .vtfixup (VT_01) -> 1).
    AutoIT3CSharpDll.il ohne Änderung

    Spoiler anzeigen


    AutoIT3CSharpDll.il mit Änderung
    Änderungen sind mit // ***************** geändert ******************** gekennzeichnet und neue Einträge mit // ***************** New ********************

    Spoiler anzeigen


    Nachdem die Änderungen durchgeführt worden sind muss der MSIL-Code wieder kompiliert werden. Dies geschieht mit folgendem Befehl.

    Code
    ilasm.exe /OUT:AutoIT3CSharpDll.dll AutoIT3CSharpDll.il /DLL


    Nun kann die C#-Dll von AutoIT aufgerufen werden.

    Spoiler anzeigen
    [autoit]

    $dll = DllOpen("AutoIT3CSharpDll.dll")

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

    $result = DllCall($dll, "int", "AddInteger", "int", 3, "int", 5)
    MsgBox(0, "AddInteger 3 + 5", $result[0])

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

    $result = DllCall($dll, "int", "MultiplyInteger", "int", 3, "int", 5)
    MsgBox(0, "MultiplyInteger 3 * 5", $result[0])

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

    $result = DllCall($dll, "str", "StringTest", "str", "Test")
    MsgBox(0, "StringTest ,Test,", $result[0])

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

    DllClose($dll)

    [/autoit]

    Im Angang befindet sich das Beispiel.

    MFG.
    RAPTOR-ONE

  • Hi,
    jup es funktioniert mit demselben vorgehen auch mit VB. Es muss nur eben der vbc anstatt des csc Compiler genutzt werden oder du lässt es einfach durch die IDE kompilieren.
    Dasselbe Beispiel was ich für C# angehängt habe, habe ich jetzt nochmal für VB gemacht.

    @Deepred wie gut hat das eigentlich bei dir funktioniert, bin nen bisschen neugierig.

    Edit: VB-Code korrigiert

    MFG.
    RAPTOR-ONE und viel Spaß beim Dll-Coden

    Einmal editiert, zuletzt von RAPTOR-ONE (17. September 2009 um 21:12)

  • Also ich habe nun ein neues Projekt namens "Test" erstellt. Mit einem Klick auf Debugen wird ja die Dll erstellt. Ist das richtig soweit? Was muss ich nun tun?

    Edit: Ja ok. Ich habe jetzt erst die Comp.txt gesehen. Vielen Dank RAPTOR-ONE für diese tolle Beispiele. Werd ich gleich mal archivieren. Weiter so!!! :thumbup: ;)

  • Hi,
    es ist soweit alles richtig.
    Die nachfolgenden schritte sind sowohl für C# als auch für VB.
    Du musst die Dll jetzt dekompilieren.

    Code
    ildasm.exe /OUT:Test.il Test.dll


    Den Pfad zum Dissassambler ildasm.exe musst du anpassen.
    Es muss in der Test.il nun folgender Befehl gesucht werden.

    Code
    .corflags 0x00000001


    Das Flag muss auf 0x00000002 verändert werden.

    Direkt dadrunter fügst du dann für jede Funktion die du exportieren willst jeweils diese beiden Befehle ein.

    Code
    .vtfixup [1] int32 fromunmanaged at VT_01
    .data VT_01 = int32(0)


    Du musst nur bei jedem einfügen den Namen der Variable ändern also VT_01, VT_02, VT_03 usw., aber das siehst du ja in dem Beispiel.

    Nun musst du deine Funktionen in der *.il Datei suchen. Die sehen ca. so aus

    Code
    .method public hidebysig static int32  AddInteger(int32 a,
                                                        int32 b) cil managed
      {
        // ***************** New ********************
        .vtentry 1 : 1
        .export [1] as AddInteger
        // ***************** New ********************
    
        // Code size       9 (0x9)
        .maxstack  2


    Da die Funktion den Namen behält den du ihr gegeben hast kannst du sie einfach suchen lassen.
    Die erste Zahl bei .vtentry und die Zahl bei export musst du bei jeder weiteren Funktion um eins erhöhen.

    Es muss also für jede .vtfixup, .data auch eine passende .vtentry, .export Zeile existieren.

    So, wenn du das alles geschaft hast kannst du die *.il Datei wieder kompilieren mit folgendem Befehl

    Code
    ilasm.exe /OUT:AutoIT3CSharpDll.dll AutoIT3CSharpDll.il /DLL


    Hier musst du auch wieder den Pfad zur ilasm.exe anpassen.

    Wenn du alles richtig gemacht hast sollte die Dll jetzt funktionieren und fals du noch Fragen hast immer her damit.

    MFG.
    RAPTOR-ONE

  • Hi,
    hab mal ein kleines Programm geschrieben mit dem Funktionen aus einer .NET-Dll exportiert werden können.
    Funktionen die Exportiert werden sollen müssen in C# "public static" und in VB "Public Shared" definiert sein.

    dotNET DLL-Exporter
    1. Dll oder il-Code Laden
    2. Funktionen auswählen die Exportiert werden sollen und den Modifizieren Button drücken
    3. Code Speichern
    5. Kompilieren lassen
    Fertig!

    Fehler bitte melden, danke.

    MFG.
    RAPTOR-ONE

    Edit: Es wir Visual Studio benötigt, da dort das Assembler und Disassembler-Tool enthalten ist

    Einmal editiert, zuletzt von RAPTOR-ONE (2. September 2009 um 22:29)