Dynamic Link Library zur Weiterverwendung in AutoIt

  • IdealGewichtsRechner - IGR

    Der IGR errechnet Ihr Idealgewicht und den BMI. Für ausreichend Humor sorgen die eingebauten Smileys.
    Bitte beachten Sie auch den Hinweis zu BMI.
    Dynamic Link Library einer autoitfremden Sprache zur Weiterverwendung in AutoIt
    kann manchmal vorteilhaft sein. Dafür spricht zum Beispiel die höhere Verarbeitungsgeschwindigkeit der autoitfremden Sprache oder das Mitführen, bündeln und bereitstellen von Ressourcen.
    Diese kleine Präsentation soll erste Anhaltspunkte liefern.

    Sprache: Deutsch
    Betriebssysteme: Windows XP, 2003, Vista, Seven
    Version: IGRv8300
    Dateigröße: 323 K

    IGR.au3
    [autoit]


    #region - TimeStamp
    ; 2011-05-16 14:31:14
    #endregion - TimeStamp

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

    #include <AVIConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    Opt('GUIOnEventMode', 1)

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

    Global $title = "IGR & BMI v8.3"
    Global $dll = @ScriptDir & "\igr.dll"
    Global $dllo = DllOpen($dll) ; Open the DLL (faster with DLL-handle)
    Global $ini = @ScriptDir & "\igr.ini"
    Global $var = IniRead($ini, "Settings", "maennlich", "0")

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

    If Not FileExists($dll) Then Exit _
    MsgBox(262144 + 16, 'Error ' & $title, $dll & @CRLF & @CRLF & "File Not Found ! ")

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

    Global $GUI = GUICreate($title, 258, 322)
    GUISetOnEvent(-3, '_quit')
    GUICtrlCreateGroup("Ihre Eingaben", 16, 16, 225, 120)
    Global $tb_Gewicht = GUICtrlCreateInput("Gewicht in kg", 32, 48, 73, 21, 8192)
    GUICtrlSetState(-1, 256)
    Global $tb_Groesse = GUICtrlCreateInput("Größe in cm", 32, 88, 73, 21, 8192)
    Global $rb_Maennlich = GUICtrlCreateRadio("&männlich", 144, 56, 65, 17)
    Global $rb_Weiblich = GUICtrlCreateRadio("&weiblich", 144, 88, 65, 17)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    Global $ico_Icon = GUICtrlCreateIcon($dll, 2, 200, 160, 32, 32)
    Global $lb_BMI = GUICtrlCreateLabel("Willkommen,", 16, 160, 180, 20)
    GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
    GUICtrlSetColor(-1, 0x800000)
    Global $lb_Klasse = GUICtrlCreateLabel("ich errechne Ihren BMI", 16, 192, 210, 20)
    GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
    GUICtrlSetColor(-1, 0x800000)
    Global $lb_IGR = GUICtrlCreateLabel("und das Idealgewicht !", 16, 224, 210, 20)
    GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
    GUICtrlSetColor(-1, 0x800000)
    Global $bn_About = GUICtrlCreateButton("&About", 15, 256, 55, 22, 0)
    GUICtrlSetOnEvent(-1, '_about')
    Global $bn_Hinweis = GUICtrlCreateButton("&Info", 75, 256, 55, 22, 0)
    GUICtrlSetOnEvent(-1, '_Info')
    Global $bn_Del = GUICtrlCreateButton("&Del", 135, 256, 50, 22, 0)
    GUICtrlSetOnEvent(-1, '_Del')
    Global $bn_Update = GUICtrlCreateButton("&Update", 190, 256, 55, 22, 0)
    GUICtrlSetOnEvent(-1, '_UpdateCheck')
    Global $bn_Rechnen = GUICtrlCreateButton("&Rechnen", 15, 290, 170, 22, 0)
    GUICtrlSetOnEvent(-1, '_start')
    GUICtrlSetState(-1, 512)
    Global $bn_Close = GUICtrlCreateButton("&Beenden", 190, 290, 55, 22, 0)
    GUICtrlSetOnEvent(-1, '_quit')

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

    Switch $var
    Case 1
    GUICtrlSetState($rb_Maennlich, 1)
    Case 0
    GUICtrlSetState($rb_Weiblich, 1)
    EndSwitch

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

    GUISetState(@SW_SHOW, $GUI)

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

    Global $AboutGUI = GUICreate("About", 324, 260, -1, -1, 0x00080000, -1, $GUI)
    GUICtrlCreateGroup("", 8, 8, 300, 185)
    GUICtrlCreateLabel("Produkt-Name :", 88, 24, 78, 17)
    GUICtrlCreateLabel("IdealGewicht und BMI Rechner", 88, 48, 155, 17)
    GUICtrlCreateAvi($dll, 150, 24, 48, 40, 44, 4)
    GUICtrlCreateLabel("Version :", 88, 72, 45, 17)
    GUICtrlCreateLabel("8.3.03 Build 2011-05-16", 88, 96, 117, 17)
    GUICtrlCreateLabel('© ' & @YEAR & ' by Ritzelrocker04', 88, 120, 133, 17)
    GUICtrlCreateIcon($dll, 1, 24, 128, 32, 32)
    GUICtrlCreateLabel("Erstellt mit AutoIt", 88, 144, 86, 17)
    GUICtrlCreateLabel("Dank an das http://www.AutoIt.de - Team", 88, 168, 213, 17)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    Global $bn_Ok = GUICtrlCreateButton("&OK", 120, 200, 75, 22)
    GUICtrlSetOnEvent(-1, '_aboutClose')

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

    While Sleep(1000)
    WEnd

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

    Func _start()
    Switch GUICtrlRead($rb_Maennlich)
    Case 1
    IniWrite($ini, "Settings", "maennlich", "1")
    Case 4
    IniWrite($ini, "Settings", "maennlich", "0")
    EndSwitch
    If GUICtrlRead($tb_Groesse) >= 100 And GUICtrlRead($tb_Groesse) <= 230 Then
    ;### DLL BMI berechnen ###
    Global $bmi = DllCall($dllo, "double:cdecl", "_bmi", "double", GUICtrlRead($tb_Gewicht), "double", GUICtrlRead($tb_Groesse))
    ;Global $_Ergebnis_BMI = Round($bmi[0], 2)
    Global $_Ergebnis_BMI = Round($bmi[0], 2)
    If BitAND(GUICtrlRead($rb_Maennlich), 1) = 1 Then
    ;### IdealGewicht eines Mannes berechnen ###
    Global $_Ergebnis_IGR = _IdealGewicht()

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

    Switch $_Ergebnis_BMI
    Case 0 To 20
    Global $_Ergebnis_Klasse = "Sie haben Untergewicht ,"
    Global $_Smileys = "5"
    Case 20 To 25
    $_Ergebnis_Klasse = "Sie haben Normalgewicht ,"
    $_Smileys = "2"
    Case 25 To 30
    $_Ergebnis_Klasse = "Sie haben Übergewicht ,"
    $_Smileys = "4"
    Case 30 To 50
    $_Ergebnis_Klasse = "Sie haben starkes Übergewicht ,"
    $_Smileys = "3"
    Case Else
    $_Ergebnis_BMI = "erstaunlich"
    $_Ergebnis_IGR = "?"
    $_Ergebnis_Klasse = "es bleibt besser unser Geheimnis ,"
    $_Smileys = "8"
    EndSwitch
    Else
    ;### IdealGewicht einer Frau berechnen ###
    $_Ergebnis_IGR = _IdealGewicht()

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

    Switch $_Ergebnis_BMI
    Case 0 To 19
    $_Ergebnis_Klasse = "Sie haben Untergewicht ,"
    $_Smileys = "5"
    Case 19 To 24
    $_Ergebnis_Klasse = "Sie haben Normalgewicht ,"
    $_Smileys = "2"
    Case 24 To 30
    $_Ergebnis_Klasse = "Sie haben Übergewicht ,"
    $_Smileys = "4"
    Case 30 To 50
    $_Ergebnis_Klasse = "Sie haben starkes Übergewicht ,"
    $_Smileys = "3"
    Case Else
    $_Ergebnis_BMI = "erstaunlich"
    $_Ergebnis_IGR = "?"
    $_Ergebnis_Klasse = "es bleibt besser unser Geheimnis ,"
    $_Smileys = "8"
    EndSwitch
    EndIf
    GUICtrlSetData($lb_BMI, "Ihr BMI ist " & $_Ergebnis_BMI & " und")
    GUICtrlSetData($lb_Klasse, $_Ergebnis_Klasse)
    GUICtrlSetData($lb_IGR, "das Idealgewicht beträgt : " & $_Ergebnis_IGR & " kg")
    GUICtrlSetImage($ico_Icon, $dll, $_Smileys)
    Else
    GUICtrlSetData($lb_BMI, "Sorry ,")
    GUICtrlSetData($lb_Klasse, "aber Ihre Größe bitte nur in")
    GUICtrlSetData($lb_IGR, "cm von 100 bis 230 eingeben !")
    GUICtrlSetImage($ico_Icon, $dll, $_Smileys)
    EndIf
    If GUICtrlRead($tb_Gewicht) = 0 Then
    GUICtrlSetData($lb_BMI, "Sorry ,")
    GUICtrlSetData($lb_Klasse, "Sie müssen noch")
    GUICtrlSetData($lb_IGR, "Ihr Gewicht in kg eingeben !")
    GUICtrlSetImage($ico_Icon, $dll, $_Smileys)
    EndIf
    EndFunc ;==>_start

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

    Func _Info()
    MsgBox(64, "Wichtige Information !", "Der BMI unterscheidet nicht zwischen Fett- und Muskelmasse." & @CRLF & _
    "Sportler, Bodybuilder und Schwerstarbeiter, die viele Muskel-Kilos auf die Waage bringen," & @CRLF & _
    "gehören nach dem BMI bereits in die Kategorie „übergewichtig“, obwohl ihr Körperfett-Anteil " & @TAB & @CR & _
    "nur gering ist. " & @CRLF & _
    "Der BMI gilt ebenfalls nicht für Schwangere und stillende Mütter, kranke und alte Menschen " & @CRLF & _
    "und Kinder im Wachstum. Überdies werden sehr kleine Menschen ( kleiner als 150 cm) oft " & @CRLF & _
    "falsch zu hoch eingestuft, sehr große Menschen (größer als 190 cm) dagegen zu niedrig " & @CRLF & _
    "bewertet. Ähnliche Einschränkungen gibt es für Menschen mit schlankem Körperbau, " & @CRLF & _
    "die häufig zu niedrig eingestuft werden, und untersetzte Menschen," & @CRLF & _
    "die zu schnell als zu dick klassifiziert werden." & @CRLF & _
    " " & @CRLF & _
    "Der BMI-Rechner soll nur einen ersten Anhalspunkt geben." & @CRLF & _
    "Wer es genauer wissen will, ob er abspecken sollte, misst besser seinen persönlichen" & @CRLF & _
    "Körperfettanteil, z.B. mit einer speziellen Körperfettwaage!")
    EndFunc ;==>_Info

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

    Func _quit()
    DllClose($dllo) ; Dont forget to close your DLL-Handle
    Exit
    EndFunc ;==>_quit

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

    Func _Del()
    GUICtrlSetData($tb_Gewicht, "")
    GUICtrlSetData($tb_Groesse, "")

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

    GUICtrlSetData($lb_BMI, "Willkommen,")
    GUICtrlSetData($lb_Klasse, "ich errechne Ihren BMI")
    GUICtrlSetData($lb_IGR, "und das Idealgewicht !")
    GUICtrlSetImage($ico_Icon, $dll, 2)
    EndFunc ;==>_Del

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

    Func _about()
    GUISetState(@SW_SHOW, $AboutGUI)
    EndFunc ;==>_about

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

    Func _aboutClose()
    GUISetState(@SW_HIDE, $AboutGUI)
    EndFunc ;==>_aboutClose

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

    Func _UpdateCheck()
    ShellExecute("http://ritzelrocker04.bplaced.net/thema1.htm")
    EndFunc ;==>_UpdateCheck

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

    Func _IdealGewicht()
    Local $op, $igr
    Switch GUICtrlRead($rb_Maennlich)
    Case 1
    $op = 0.9
    Case 4
    $op = 0.85
    EndSwitch
    ;### DLL IdealGewicht-Rechnung ###
    $igr = DllCall($dllo, "float:cdecl", "_ig", "int", GUICtrlRead($tb_Groesse), "float", $op)
    ;Local $_Ergebnis_IGR = Round($igr[0], 2)
    Local $_Ergebnis_IGR = Round($igr[0], 2)
    Return $_Ergebnis_IGR
    EndFunc ;==>_IdealGewicht

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

    ; Ende

    [/autoit]
    dll.cpp

    Edit: Anpassungen vorgenommen, siehe Post #8 !

  • Dafür spricht zum Beispiel die höhere Verarbeitungsgeschwindigkeit der autoitfremden Sprache oder das Mitführen, bündeln und bereitstellen von Ressourcen.


    Ja das mag sein aber diese kleinen Berechnungen dauern maximal 0.01ms. Es ist also Sinnfrei hier eine DLL zu nutzen und das DLL's schneller arbeiten als AutoIt ist auch keine Neuigkeit mehr.

  • Da Du das schon kennst, hast Du noch weitere Hinweise/Ratschläge?

    1. Wenn man eine reine 32-Bit Dll erstellt wird man sie nicht ohne weiteres mit einem AutoIt-x64-Skript zum laufen bekommen.
    In diesen Fällen sollte also am Anfang des Skriptes die Zeile "#AutoIt3Wrapper_UseX64=n"

    2. Der Performance-Vorteil von nativen Code wird bei solch kleinen Berechnungen sofort vom enstehenden Overhead des Dll-Calls aufgefressen.
    Momentan trägst du im DllCall die Dll als Pfad ein.
    Das heißt bei jedem Funktionsaufruf wird die Dll geöffnet, in den Speicher geladen, die Funktion in der Funktionstabelle nachgeschlagen, die Funktion abgearbeitet und die Dll wieder geschlossen.
    Wenn man eine Dll mehrmals in einem Skript verwenden will sollte man daher die Dll mit DllOpen() öffnen.
    Um das ganze mal zu verdeutlichen hier mal ein kleines Performance-Vergleichsskript für deine igr-Funktion:

    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_UseX64=n
    Global $IdGewicht, $iT
    Global $N = 10000

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

    ; Idealgewicht mit DLL-Pfad
    Global $dll = @ScriptDir & "\igr.dll"
    $iT = TimerInit()
    For $i = 1 To $N
    $igr = DllCall($dll, "float:cdecl", "_ig", "int", 189, "float", 0.9)
    $IdGewicht = $igr[0]
    Next
    $iT = TimerDiff($iT) / $N
    ConsoleWrite("igr mit DLL mit Pfad: " & Round($iT, 3) & "ms" & @TAB & "Ergebnis: " & Round($IdGewicht, 1) & @CRLF)

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

    ; Idealgewicht mit DLL-Open
    $dll = DllOpen(@ScriptDir & "\igr.dll")
    $iT = TimerInit()
    For $i = 1 To $N
    $igr = DllCall($dll, "float:cdecl", "_ig", "int", 189, "float", 0.9)
    $IdGewicht = $igr[0]
    Next
    DllClose($dll)
    $iT = TimerDiff($iT) / $N
    ConsoleWrite("igr mit DLL mit Dll-Open: " & Round($iT, 3) & "ms" & @TAB & "Ergebnis: " & Round($IdGewicht, 1) & @CRLF)

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

    ; Idealgewicht mit AutoIt
    $iT = TimerInit()
    For $i = 1 To $N
    $IdGewicht = _igr(189, 0.9)
    Next
    $iT = TimerDiff($iT) / $N
    ConsoleWrite("igr mit AutoIt: " & Round($iT, 3) & "ms" & @TAB & "Ergebnis: " & Round($IdGewicht, 1) & @CRLF)

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

    Func _igr(Const $iS, Const $dF)
    Return ($iS - 100) * $dF
    EndFunc ;==>_igr

    [/autoit]