DLL Open / Call zu langsam

  • Hallo Leude...

    Ich habe eine "inpout32.dll" mit der ich einzelne und/oder mehrere Bits aus den 3 Registern der Parallelen Schnittstelle schalte und/oder lese.

    Beisp.:

    [autoit]


    $Dll = DLLOpen("inpout32.dll")

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

    DllCall($DLL, "int", "Out32", "int", $EA_Adresse_des_Port, "int", $Zu_schreibender_DezimalWert)

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

    Diesen DLLCall möchte ich so schnell wie möglich ausführen. Derzeit dauert der Aufruf bei mir etwa 10 ms, was für meine Bedürfnisse noch zu langsam ist.
    Da ich in Sachen DLL noch fast NEWBE bin, frage ich: "Kann ich den Aufruf noch beschleunigen?
    Bin durch " DLLStructCreate " & co. leider nicht durchgestiegen..

    Danke
    Gruß

    ... wasweisichdennschon...

    Einmal editiert, zuletzt von Chrischn (29. Januar 2010 um 15:26)

  • Ok. Danke erstmal für´s Auslöschen meiner Hoffnungen...

    Wofür wendet man denn die DLLStructCreate an?
    Der Name dieser Funktion erklärt sich ja fast selbst. Klingt als soll hier sowas wie eine DLL-Function gebaut werden.
    Aber ne Erklärung oder ne Anwendung wär schon nicht schlecht.

    ... wasweisichdennschon...

  • du könntest den Aufruf eventuell noch durch die Verwendung der Ordinalzahl der Funktion statt ihres Namens beschleunigen, aber 10ms sind für AutoIt schon gut ;) der DLLCall muss durch den Interpreter erst in Maschinencode zusammengebaut werden, das dauert eben auch seine Zeit.

  • Z.B. mit dem >>Dependency-Walker<<.

    Darf ich fragen wie du den Wert von 10ms ermittelst?

    Ansonsten wär vielleicht noch zu sagen das wenn man eine DLL mehrmals im Sript benutzt die DLL mit DLLOpen öffnen sollte und dann dieses Handle einträgt statt den DLL-Namen. (was du oben ja schon getan hast)

    Wenn dir das immer noch nicht reicht ist der Moment gekommen wo du an die Grenzen von AutoIt gestoßen bist.

  • Na klar,

    es sind 1- 10 ms. Eher der Durchschnitt. Einmal per TimerDiff und einmal visuell. Mein LPT-gesteuerter Schrittmotor hat 200 Schritte. Und bei ca 5ms pro Schritt kann man beim zusehen einschlafen... Drehzahl kannst dir ja ausrechnen... (1 Umdr. / sek entspr. 60 /min. ) ... ZU_LANGSAM("viel")

    ... wasweisichdennschon...

  • schreib dir ne wrapper-DLL in z.B. freebasic. Da machst du dann eine Funktion, die eine bestimmte Zahl von Schritten ausführt ;) Diese kannst du dann in AutoIt aufrufen.

  • ja das sind 100 Aufrufe der DLL / sek. Für manche Anwendungen mehr als genug.. Lauflicht.. Modelleisenbahn... Digitale eingänge... aber ein 200-Schritt-Motor... bäääää

    ... wasweisichdennschon...

  • hmmm, in Turbo/Powerbasic hatte ich für diese Sachen den Inlineassembler bemüht. Dort konnte man direkt die COM-Ports beeinflussen.
    Dann limitiert nur noch die 102kbps-Schnittstelle den Speed :rock:

    Für Inlineassembler in AutoIt gibt es 2 Möglichkeiten, schau mal im engl. Forum, ich würde die "schöne" Variante bevorzugen.

    Spoiler anzeigen

    oder aber so, aber "optisch" nicht so schöner 8) code^^

    Spoiler anzeigen
    [autoit]

    ; by trancexx
    #include <GUIConstantsEx.au3>
    #include <Memory.au3>

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

    Opt("GUIOnEventMode", 1)

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

    Global Const $STM_SETIMAGE = 370

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

    Global Const $iWidth = 800
    Global Const $iHeight = 470

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

    GUICreate("", $iWidth, $iHeight)
    GUISetOnEvent(-3, "_Quit")
    GUISetBkColor(0)

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

    Global $hPic = GUICtrlCreatePic("", 0, 0, $iWidth, $iHeight)

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

    Global $iSize = $iWidth * $iHeight
    Global $tBits = DllStructCreate("int[" & $iSize & "]")
    Global $pBits = DllStructGetPtr($tBits)

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

    Global $hBitmap, $aCall, $iHMsg
    Global $hPicHandle = GUICtrlGetHandle($hPic)

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

    Global $tRandom = DllStructCreate("dword")
    Global $pRandom = DllStructGetPtr($tRandom)

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

    GUISetState()

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

    Global $aRtlRandomEx = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("ntdll.dll"), "str", "RtlRandomEx")
    Global $pRtlRandomEx = $aRtlRandomEx[0]

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

    Global $aRtlMoveMemory = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("kernel32.dll"), "str", "RtlMoveMemory")
    Global $pRtlMoveMemory = $aRtlMoveMemory[0]

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

    Global $aSendMessageW = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("user32.dll"), "str", "SendMessageW")
    Global $pSendMessageW = $aSendMessageW[0]

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

    Global $aDeleteObject = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("gdi32.dll"), "str", "DeleteObject")
    Global $pDeleteObject = $aDeleteObject[0]

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

    Global $aCreateBitmap = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("gdi32.dll"), "str", "CreateBitmap")
    Global $pCreateBitmap = $aCreateBitmap[0]

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

    Global $pRemoteCode = _MemVirtualAlloc(0, 512, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)

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

    Local $tCodeBuffer = DllStructCreate("byte[512]", $pRemoteCode)

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

    #Region Assemply
    DllStructSetData($tCodeBuffer, 1, _
    "0x" & _
    "33DB" & _ ; xor ebx, ebx
    "68" & SwapEndian($pRandom) & _ ; push $pRandom
    "B8" & SwapEndian($pRtlRandomEx) & _ ; mov eax, RtlRandomEx
    "FFD0" & _ ; call eax
    "8BCB" & _ ; mov ecx, ebx
    "69C9" & SwapEndian(4) & _ ; imul ecx, 4
    "81C1" & SwapEndian($pBits) & _ ; add ecx, $pBits
    "68" & SwapEndian(3) & _ ; push 3 bytes
    "68" & SwapEndian($pRandom) & _ ; push $pRandom
    "51" & _ ; push ecx
    "B8" & SwapEndian($pRtlMoveMemory) & _ ; mov eax, RtlMoveMemory
    "FFD0" & _ ; call eax
    "43" & _ ; inc ebx
    "81FB" & SwapEndian($iSize) & _ ; cmp ebx, $iSize; <- compare ebx with $iSize
    "75" & Hex(256 - 53, 2) & _ ; jne -53 bytes; <- this is saying go back and do it again if not equal
    "68" & SwapEndian($pBits) & _ ; push $pBits
    "68" & SwapEndian(32) & _ ; push BitsPerPel
    "68" & SwapEndian(1) & _ ; push Planes
    "68" & SwapEndian($iHeight) & _ ; push $iHeight
    "68" & SwapEndian($iWidth) & _ ; push $iWidth
    "B8" & SwapEndian($pCreateBitmap) & _ ; mov eax, CreateBitmap
    "FFD0" & _ ; call eax
    "50" & _ ; push eax
    "68" & SwapEndian(0) & _ ; push IMAGE_BITMAP
    "68" & SwapEndian($STM_SETIMAGE) & _ ; push STM_SETIMAGE
    "68" & SwapEndian($hPicHandle) & _ ; push $hPicHandle
    "B8" & SwapEndian($pSendMessageW) & _ ; mov eax, SendMessageW
    "FFD0" & _ ; call eax
    "50" & _ ; push eax
    "B8" & SwapEndian($pDeleteObject) & _ ; mov eax, DeleteObject
    "FFD0" & _ ; call eax
    "C3" _ ; ret
    )
    #EndRegion Assembly

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

    ;While 1

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

    #region Assembly

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


    $t=timerinit()
    for $i=1 to 10
    DllCall("user32.dll", "int", "CallWindowProcW", _
    "ptr", $pRemoteCode, _
    "int", 0, _
    "int", 0, _
    "int", 0, _
    "int", 0)
    next
    #endregion Assembly
    $x=timerdiff($t)
    msgbox(0,0,$x)
    Sleep(10)
    while 1
    WEnd

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

    Func SwapEndian($iValue)
    Return Hex(Binary($iValue))
    EndFunc ;==>SwapEndian

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

    Func _Quit()
    Exit
    EndFunc ;==>_Quit

    [/autoit]

    damit ist das +dll-gefrickel dann auch vorbei...und Geschwindigkeitsmäßig wird es auch von C-Routinen nicht zu toppen sein

  • schreib dir ne wrapper-DLL in z.B. freebasic. Da machst du dann eine Funktion, die eine bestimmte Zahl von Schritten ausführt ;) Diese kannst du dann in AutoIt aufrufen.

    klingt vielleicht wie vom Anfänger, aber.... UND WIE?!!?!?!

    nehmen wir mal an, ich hätte keinen Plan, wie die inpout32.dll aussieht ... ich weis lediglich, wie ich die Funktionen in AI aufrufe.
    ...Dumm sein ist manchmal erniedrigend...
    ich hoffe, ich muss mich nicht erst 1/2 Jahr einarbeiten, bovor ich das hier fertig bekomme..

    ... wasweisichdennschon...

  • Hallo! Danke.
    Sieht interessant aus. Aber ich glaube, wenn ich genau wüsste, was in der inpout32.dll drin steht, dann wäre ich in der Lage sie so zu verändern, wie ich´s gern hätte.
    Das weiß ich aber leider nicht.
    Damit tuh ich mich grad ein bischen schwer...

    Kann ich die dll irgendwie auseinanderbauen um reinzusehen?

    ... wasweisichdennschon...


  • Sieht interessant aus. Aber ich glaube, wenn ich genau wüsste, was in der inpout32.dll drin steht, dann wäre ich in der Lage sie so zu verändern, wie ich´s gern hätte.


    Wenn du die DLL ändern willst, musst du das aber in c++ machen, da sie damit geschrieben wurde und das ist noch viel schwieriger als FreeBasic. Aber HIER gibt es DLL und quellcode, falls du es wirklich versuchen willst.

    Einfacher ist auf jeden Fall, eine 2. DLL zu schreiben, die intern die Funktionen der normalen inpout32.dll verwendet und zusätzliche Funktionen zur Verfügung stellt.


  • Wenn du die DLL ändern willst, musst du das aber in c++ machen, da sie damit geschrieben wurde und das ist noch viel schwieriger als FreeBasic. Aber HIER gibt es DLL und quellcode, falls du es wirklich versuchen willst.

    Einfacher ist auf jeden Fall, eine 2. DLL zu schreiben, die intern die Funktionen der normalen inpout32.dll verwendet und zusätzliche Funktionen zur Verfügung stellt.

    So,.. hab mir den Quellcode und die Pjojektdateien angesehen. Bin leider genauso schlau wie vorher.
    Das mit dem "einfach ne 2. DLL schreiben" krieg ich aber denke ich nicht gebacken... bin da wie schon erwähnt Jungfrau.

    ... wasweisichdennschon...