DLL Verständniss verbessern

  • Hi,

    ich würde mich gern etwas in die Benutzung von .dll Dateien einarbeiten, wissen was man mit ihnen anstellen kann wozu sie normalerweise verwendet werden.
    Ich habe in anderen Scripten im AutoIt-Board gesehen das sie geöffnet werden und etwas aus ihnen ausgelesen hier würde ich auch gerne wissen wie man herausfindet was sie beinhalten/ was man aus ihnen auslesen könnte.
    Alles in allem würde ich gern mehr über die Verwendung von Funktionen wie dllcall und dllread lernen.
    Ich habe mir die Hilfe Dateien angeschaut aber ich bin daraus nicht schlau geworden.
    Es wäre sehr nett wenn mir jemand eine kleine Zusammenfassung geben könnte.

    Mfg
    monkey

    Monkey - die finale Potenz von göttlich!
    Sloganizer

  • Hi,

    erste Anlaufstelle, damit man erst einmal versteht was DLLs überhaupt sind ist wie so oft MSDN: http://msdn2.microsoft.com/en-us/library/1ez7dh12(VS.80).aspx

    Um die Funktionen, die in einer DLL public sind herauszufinden benutzt man am Besten den Depencency Walker: http://www.dependencywalker.com/

    Nun braucht man in den meisten Fällen noch eine Dokumentation zu der DLL, in der die DLL-Funktionen beschrieben sind (Ohne Doku ist es oft schwer die Funktionen korrekt aufzurufen). Bei Microsoft DLLs MSDN benutzen, bei DLLs von Drittherstellern nachschauen, ob es ein PDF oder Ähnliches gibt.

    In AutoIt gestaltet sich die Implementation dann sehr einfach. Am besten öffnet man die DLL mittels OnAutoItStart-Funktion am Anfang mit DLLOpen und ruft die Funktionen dann mit DLLCall auf, wozu man sich am besten für jede Funktion eine UDF schreibt. Am Ende des Skriptes einmal DLLClose und fertig ists.

  • Wenn ich mir das so angucke, und en bisschen was ausprobiere ist das noch etwas komplex.

    Ich versuche die BlockInput Function aus der user32.dll zu verwenden aber ich weiss nicht wie ich die benutzen soll.

    BOOL BlockInput(
    BOOL fBlockIt
    );

    Ich habe das Problem das ich nicht weiss wie ich die Variable fBlockIt verändern kann
    So funktioniert es nicht, aber warum?

    [autoit]

    dllcall("user32.dll", "int", "BlcokInput", "bool", "TRUE")

    [/autoit]

    Mfg
    monkey

    Monkey - die finale Potenz von göttlich!
    Sloganizer

    • Offizieller Beitrag

    Hallo,

    erst mal hast Du einen schreibfehler bei BlockInput (o und c ist vertauscht).

    DllCall kennt den Datentyp BOOL nicht, in C++ wird dieser Datentyp aus Long definiert. Dabei ist 0 = False und alles ungleich 0 ist True.

    Das folgende Beispiel schaltet 15 Sekunden Maus und Tastatur ab und gibt sie dann wieder frei.

    [autoit]

    DllCall("user32.dll", "long", "BlockInput", "long", 1)
    MsgBox(0,"", "Maus und Tastatur sind jetzt blockiert!", 15)
    DllCall("user32.dll", "long", "BlockInput", "long", 0)
    MsgBox(0,"", "Maus und Tastatur sind jetzt wieder frei!")

    [/autoit]
  • Danke für die Antwort, aber das wirft mir die nächste Frage auf, wie erkenne ich was ich verwenden muss?(long, str, int ....)

    Und wie weiss ich was is als Wert eintragen soll? (0, 1)

    Mfg
    monkey

    Monkey - die finale Potenz von göttlich!
    Sloganizer

    • Offizieller Beitrag

    Dazu sollte man sich die Funktionsbeschreibung für BlockInput bei MSDN anschauen. In der Hilfe zu DllCall findest Du die verfügbaren Typen.
    Was auch sehr hilfreich ist ist der ApiViewer und die Seite http://www.activevb.de, die ist zwar für VisualBasic aber liefert einen ersten Überblick.

  • Ich hab mir die Funktion auf MSDN angeschaut, durchgelesen, dann hab ich das Prinzip von dem Beispiel in der Hilfe Datei versucht auf BlockInput zu verwenden, mit mäßigem erfolg...


    Ich dachte, weil am anfang der Funktion int steht, ist das auch glichzeitig der return type

    Code
    int MessageBox(      
        HWND hWnd,
        LPCTSTR lpText,
        LPCTSTR lpCaption,
        UINT uType
    );

    Mein Erster versuch sah so aus.

    [autoit]

    dllcall("user32.dll", "Bool", "BlcokInput", "bool", "TRUE")

    [/autoit]


    Und in MSDN hab ich nirgends gefunden etwas gefunden welchen return type die Funktion denn nun hat.

    Also ist meine Frage wie kann man das unterscheiden?(Ohne eine Zusammenfassung durch ein Programm)

    Mfg
    monkey

    Monkey - die finale Potenz von göttlich!
    Sloganizer

  • Aaaalso...

    Ich versuche mal einen Grobüberblick zu geben:

    DLL-Dateien sind Code-Bibliotheken, welche ausführbare Funktionen beinhalten, welche man wiederum in seinen Programmen nutzen kann.
    So wie man bei AutoIt zusätzliche Funktionen aus Zusatz-Dateien per #include einbinden kann kann man genauso die Funktionen von DLL-Dateien nutzen.
    Dazu braucht man Informationen wie die Funktion heißt und welche Parameter sie hat - vor allem aber welchen Datentyp!

    Das ist der eigentliche Knackpunkt der für reine AutoIt´ler wohl das schwierige daran sein wird.
    In AutoIt muss man sich keine Gedanken machen welcher Typ eine Variable ist, also ob die beinhalteten Daten z.b eine Ganzzahl (Integer) sind oder doch eine Zahl mit Nachkommastellen (Gleitkommazahl) oder halt nur ein Zeichen (Char), oder sogar eine Zeichenkette bestehend aus mehreren Zeichen (String).
    Es gibt noch viele andere Möglichkeiten.
    In AutoIt kann einem das egal sein - der Variablentyp wird anhand seiner Verwendung festgelegt.
    Um mit DLL-Dateien zu arbeiten muss man aber Variablen und Parametern mit einem exakten Datentyp definieren.
    Diese Informationen muss man aus der zugehörigen Referenz zu dieser Funktion heraus lesen.
    Tools wie Dependency Walker helfen da nur bedingt da diese keine Aussage über die Funktion der Parameter liefern.

    Gehen wir also mal an ein Beispiel heran - ich nehm mal monkeys Beispiel mit der Message-Box:

    Lesen wir uns mal die Doku dazu auf msdn durch: >>MessageBox<<

    Aus der Synthax können wir heraus lesen das die Funktion "MessageBox" heißt, dass sie ein Integer-Wert als Rückgabewert zurück gibt und das sie 4 Parameter benötigt.
    Der erste Parameter ist vom Datentyp ein Window-Handle - laut Doku gibt man damit ein "Owner"-Window an welchen die Message-Box vermutlich gekoppelt werden kann (keine wirkliche Ahnung was die damit meinen) - wir wollen das jedenfalls nicht und können stattdessen auch einfach "0" eintragen - damit erhalten wir eine eigentständige Message-Box,
    Der 2. Parameter ist vom Typ ein Pointer auf einen String (Zeichenkette) welcher den anzuzeigenden Text beinhaltet.
    Das ist nun etwas fies da Pointer für den Anfang etwas schwierig zu verstehen sind.
    Im Grunde gesagt wird dabei nicht der Wert einer Variable übergeben sondern lediglich eine Information darüber wo der Wert im Speicher zu finden ist.
    Das Konzept der Pointer erfordert bisschen Übung - wer schonmal mit C oder ähnlichem gearbeitet hatte der wird damit sicher schonmal zu tun gehabt haben.
    Also gut - wir merken uns erstmal: Wir brauchen eine Stringvariable in der der Text steht und der Funktion übergeben wir dann einen Zeigen auf diese Variable.
    Genauso beim 3. Parameter - dieser beinhaltet den Titeltext - ansonsten alles gleich.
    Der 4. Parameter ist ein vorzeichenloser Integer-Wert.
    Dieser beinhaltet die Optionen für die Message-Box.
    In der Doku dazu findet man viele Konstanten welche man da einsetzen kann.
    AutoIt kann damit aber nichts anfangen da diese nirgends deklariert sind - wir brauchen also den jeweiligen Wert der Konstanten welchen wir dann direkt als Zahl einsetzen können - die Werte bekommen wir mit dem API-Viewer den Bernd verlinkt hatte heraus.

    Gut - alles zusammengesetzt kommt nun folgendes AutoIt-Konstrukt heraus (hab mal in als 4. Parameter MB_TOPMOST und MB_YESNO als Option eingetragen):

    Spoiler anzeigen
    [autoit]

    $Text = "Das ist der BeispielText!!!"
    $Caption = "Überschrift"

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

    $struct1 = DllStructCreate('char[' & StringLen($Text) + 1 & ']')
    DllStructSetData($struct1, 1, $Text)
    $struct2 = DllStructCreate('char[' & StringLen($Caption) + 1 & ']')
    DllStructSetData($struct2, 1, $Caption)

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

    $Return = DllCall("user32.dll", "int", "MessageBox", "HWND", 0,"ptr", DllStructGetPtr($struct1), "ptr", DllStructGetPtr($struct2), "uint", 0x4 + 0x40000)

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

    MsgBox(0,"", "Rückgabewert der DLLCall-Funktion:" & @CRLF & @CRLF & $Return[0])

    [/autoit]

    Wichtig ist vielleicht noch zu erwähnen das der Rückgabewert einer DLLCall-Funktion so gut wie immer ein Array zurückgibt.

    So ich hoffe das hilft erstmal bisschen einen groben Überblick über DLL´s und deren Verwendung in AutoIt zu bekommen.

    Einmal editiert, zuletzt von AspirinJunkie (14. Dezember 2007 um 20:44)

  • wooooow...

    das nen ich mal ein Beitreg :)

    THX

    Zitat

    Pointer to a null-terminated string that contains the dialog box title. If this parameter is NULL, the default title Error is used.

    lol^^ bei Microsoft ist der Standardtitel Error^^


    ich wollte noch irgendwas sinnvolles sagen^^ habs aber vergessen... naja ich edite wenn es mir wieder einfällt :)

    edit: kannst du den apiviewer mal ein bisschen erklären?^^ ich versteh das nicht ganz :/

    edit2: naja jetzt kapier ichs so halb... aber gibt es auch noch eine funktionsbeschreibung dafür?

    mfg

    derda

    2 Mal editiert, zuletzt von derda (19. November 2007 um 20:33)

  • :musik1: :musik1: :musik1: :musik1: :musik1: :musik1: :musik1: :musik1: :musik1: :musik1: :musik1: :musik1: :musik1: :musik1: :musik1: :musik1: :rofl: :rofl: :rofl: :rofl: :rofl: :rofl: :rofl: :rofl: :rofl: :rofl: :rofl: :rofl: :rofl: :rofl: :rofl: :rofl:

    Projekte: Keine größeren (und fertigen)
    Gegen Internetzensur:
    https://epetitionen.bundestag.de/index.php?acti…s;petition=3860
    (Zeichnungsfrist abgelaufen)
    __________________________________________________________________________________________________________________________________
    Dieser Beitrag wurde bereits 264 mal editiert, zuletzt von »Fast2« (30. Februar 2009, 12:99)

  • Tut mit leid das ich das Thema schon wieder aufwärmen muss aber bei mir sind da immernoch einige Unklarheiten vorhanden.

    Angenommen wir wollen in der user32.dll die Funktion AnimateWindow() benutzen

    Spoiler anzeigen
    Code
    BOOL AnimateWindow(
     HWND hwnd,
     DWORD dwTime,
     DWORD dwFlags
     );

    Dann ist der Rückgabewert BOOL aber da DllCall BOOL nicht kennt ist es also long so wie ich das von Bernd670 verstanden habe.
    So und jetzt fangen die Probleme an.

    Autoit verlang einen Type und einen Parameter.

    [autoit]

    DllCall ( "dll", "return type", "function" [, "type1", param1 [, "type n", param n]] )

    [/autoit]

    So wie ich das sehe ist der Type bei beiden(dwTime, dwFlags) DWORD aber wenn ich das einsetze dann tut sich da nichts.
    In der Autoit Hilfe steht das DWORD eine 32bit Integer sei, das mag bei dem dwTime noch passen aber bei dwFlags sieht es für mich eher so aus als wäre es ein String.
    Aber auch dann tut sich da herzlich wenig.

    Ich hab da mal mein Glück versucht aber es hat sich nichts getan.
    Hier mein Grundgedanke:

    [autoit]

    $dll=DllOpen("user32.dll")
    $hwnd = WinGetHandle("Unbenannt - Editor")
    $tset=dllcall($dll, "long", "AnimateWindow", "hwnd", $hwnd, "DWORD", 200, "int", "AW_ACTIVATE")

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

    if $tset=0 Then
    msgbox(0, "Error", "Es ist ein Fehler aufgetreten")
    ElseIf $tset <> 0 then
    MsgBox(0, "Erfolg", "Funktion wurde erfolgreich durchgeführt.")
    EndIf
    DllClose($dll)

    [/autoit]

    Mfg
    monkey

    Monkey - die finale Potenz von göttlich!
    Sloganizer

    • Offizieller Beitrag

    Hallo,

    einfach mal im oben angesprochenen APIViewer nach AW_ACTIVATE suchen. Das sind nämlich einfach nur Konstanten:

    [autoit]

    Const $AW_ACTIVATE = 0x20000
    Const $AW_BLEND = 0x80000
    Const $AW_CENTER = 0x10
    Const $AW_HIDE = 0x10000
    Const $AW_HOR_NEGATIVE = 0x2
    Const $AW_HOR_POSITIVE = 0x1
    Const $AW_SLIDE = 0x40000
    Const $AW_VER_NEGATIVE = 0x8
    Const $AW_VER_POSITIVE = 0x4

    [/autoit]

    Der Type DWORD ist also der richtige!

  • Wenn ich dieses Script ausführe dann sollte doch eigentlich das Notepad aktiviert werden oder nicht?

    [autoit]

    $dll=DllOpen("user32.dll")
    $hwnd = WinGetHandle("Unbenannt - Editor")
    dllcall($dll, "long", "AnimateWindow", "hwnd", $hwnd, "DWORD", 200, "int", "AW_ACTIVATE")
    DllClose($dll)

    [/autoit]

    Aber da tut sich trotzdem nichts.
    ?(

    Mfg
    monkey

    Monkey - die finale Potenz von göttlich!
    Sloganizer

  • Das geht nur bei eigenen Fenstern

    Zitat von http://msdn2.microsoft.com/en-us/library/ms632669.aspx

    hwnd
    [in] Handle to the window to animate. The calling thread must own this window.


    Und Außerdem geht der Code so:

    Spoiler anzeigen
    [autoit]

    Const $AW_ACTIVATE = 0x20000
    Const $AW_BLEND = 0x80000
    Const $AW_CENTER = 0x10
    Const $AW_HIDE = 0x10000
    Const $AW_HOR_NEGATIVE = 0x2
    Const $AW_HOR_POSITIVE = 0x1
    Const $AW_SLIDE = 0x40000
    Const $AW_VER_NEGATIVE = 0x8
    Const $AW_VER_POSITIVE = 0x4

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

    $dll=DllOpen("user32.dll")
    $hwnd = WinGetHandle("AutoIt3")
    MsgBox(0, '', $hwnd)
    dllcall($dll, "int", "AnimateWindow", "hwnd", $hwnd, "dword", 200, "dword", $AW_SLIDE)
    MsgBox(0, '', @error)
    DllClose($dll)
    Exit

    [/autoit]