DllCall gibt bei Callback ein Pointer zurück --> auslesen?

    • Offizieller Beitrag

    Heyho,

    Hab ne Funktion, der ich ein Pointer zu einer Callback Funktion übergebe. Das Funktioniert (mittlerweile) auch gut, Callback wird aufgerufen. Nun bekomme ich aber anscheindend einen Pointer zu einer Struct zurück, die die DLL erstellt:

    Zitat

    short **overviewBuffers:
    overviewBuffers, a pointer to a location where
    ps2000_get_streaming_last_values() will store a pointer to its
    overview buffers that contain the sampled data. The driver creates
    the overview buffers when you call ps2000_run_streaming_ns() to
    start fast streaming.


    Jemand ne Idee wie ich den auslesen kann? DllStructGetData funktioniert hier (wie erwartend) nicht.

    Hier mal der Auszug aus der Hilfe, die komplette gibt es hier:
    http://www.picotech.com/document/pdf/ps2000pg.en-4.pdf
    [Blockierte Grafik: http://k76t.img-up.net/Unbenannt9qeh9.jpg]

    Und hier ein Auszug aus den Sourcecode (Zeile 50ff findet das Auslesen statt)

    Spoiler anzeigen
    [autoit]

    ;(c) Max Reble - 2011
    ;femto, pico, nano, micro, milli, sec
    Global Enum $PS2000_FS, $PS2000_PS, $PS2000_NS, $PS2000_US, $PS2000_MS, $PS2000_S
    Global $hPICO_CallBackRegister = DllCallbackRegister("__PICO_Callback_MyGetOverviewBuffers", "none", "short;short;ulong;short;short;ulong")

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

    Global $bGO = True

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

    Global $sPICO_DLL = "..\SDK\PS2000.dll"
    Global $hPICO_OpenDlll = DllOpen($sPICO_DLL)
    If @error Or $hPICO_OpenDlll = 0 Then Exit

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

    Global $hPICO_Handle

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

    _PICO_RunStreamingModeNS(1, $PS2000_US, 10000, 0, 100, 50000)

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

    While $bGO
    _PICO_GetStreamingLastVal()
    Sleep(100)
    WEnd

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

    Func _PICO_RunStreamingModeNS($iSampleIntervalMS = 10, $iTimeUnits = 3, $iMaxSamples = 1000, $iAutostop = 0, $iNoOfSamplesAgg = 1, $iOverviewBufferSize = 20000)
    _Log("ps2000_RunStreamingModeNS ==> ", 0)
    $aDLL = DllCall($hPICO_OpenDlll, "int", "ps2000_run_streaming_ns", "short", $hPICO_Handle, _
    "ulong", $iSampleIntervalMS, _
    "short", $iTimeUnits, _
    "ulong", $iMaxSamples, _
    "short", $iAutostop, _
    "ulong", $iNoOfSamplesAgg, _
    "ulong", $iOverviewBufferSize)
    If @error Then Return SetError(1, @error, _log("Error by DLLCall: 0x" & @error))
    If $aDLL[0] = 0 Then Return SetError(2, 0, _log("Error Return by function."))
    _log("Success")
    Return $aDLL[0]
    EndFunc ;==>_PICO_RunStreamingModeNS

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

    Func _PICO_GetStreamingLastVal()
    _Log("ps2000_GetStreamingLastVal ==> ", 0)
    $aDLL = DllCall($hPICO_OpenDlll, "short", "ps2000_get_streaming_last_values", "short", $hPICO_Handle, _
    "ptr", DllCallbackGetPtr($hPICO_CallBackRegister))
    If @error Then Return SetError(1, @error, _log("Error by DLLCall: 0x" & @error))
    If $aDLL[0] = 0 Then Return SetError(2, 0, _log("Error Return by function."))
    _log("Success")
    Return $aDLL[0]
    EndFunc ;==>_PICO_GetStreamingLastVal

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

    Func __PICO_Callback_MyGetOverviewBuffers($ptrOverviewBuffers, $iOverflow, $uiTriggeredAt, $iTriggered, $iAutostop, $nValues)
    _Log("Callback:")
    $iptr = DllStructGetData($ptrOverviewBuffers, 1)
    ConsoleWrite("ptrerr: " & @error & @LF)
    _Log("ptrOverviewBuffers: " & $ptrOverviewBuffers)
    _Log("iOverflow: " & $iOverflow)
    _Log("uiTriggeredAt: " & $uiTriggeredAt)
    _Log("iTriggered: " & $iTriggered)
    _Log("iAutoStop: " & $iAutostop)
    _Log("nValues: " & $nValues)
    EndFunc ;==>__PICO_Callback_MyGetOverviewBuffers

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

    Func _log($sLogText, $iCRLF = True)
    If $iCRLF Then $sLogText &= @CRLF
    ConsoleWrite($sLogText)
    EndFunc ;==>_log

    [/autoit]

    Gruß, und vielen Dank schon Mal :)
    Spider

  • Hi Spider,
    ich hab mich jetzt nicht genau reingefuchst, aber wenn dir die Funktion einen Pointer zurückgibt, dann kannst du sehr wohl mit dllstruct() diesen Datenbereich auslesen.
    Einfach an der Position des Pointers mit dllstructcreate("dword[10000]",$pointer_zum_overview-Buffer) eine Struct erstellen und dann per dllstructgetdata() die Daten lesen.

    • Offizieller Beitrag

    Heyho,

    Danke erstmal für deine Antwort Andy, leider wars das noch nicht ganz. Wenn ich bei DllStructCreate() den Pointer (der übrigends immer negativ ist, gehört das so?) angebe, dann gibt mir die StructCreate Funktion zwar kein Fehler zurück, aber sobald ich versuche die Struct mit DllStructGetData auszulesen, bekomme ich ein Absturz ("AutoIt funktioniert nicht mehr", Windows Fehlermeldung: !>21:40:17 AutoIT3.exe ended.rc:255)

    Das interessante ist, dass ich bei DllStructCreate() bei dem Pointer alles mögliche hinschreiben kann (z.B. auch 219 oder so..) und er mir trotzdem keinen Fehler ausgibt bei der Create funktion, nur beim auslesen dann (den gleichen).

    Hier auch noch mal ein bisschen Sample Code in allen Möglichen Programmiersprachen:
    http://www26.zippyshare.com/v/68880485/file.html

    Spoiler anzeigen
    [autoit]


    Func __PICO_Callback_MyGetOverviewBuffers($iOverviewBuffers, $iOverflow, $uiTriggeredAt, $iTriggered, $iAutostop, $nValues)
    _Log("Callback:")

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

    $hTestStruct = DllStructCreate("dword["&$nValues&"]", $iOverviewBuffers);Funktioniert, ohne Error, allerdings kann ich bei iOverviewBuffers auch irgendeine andere Zahl einsetzen. iOverviewBuffers ist immer negativ (-4953 z.B.)
    ConsoleWrite(@error & @LF)
    $sTest = DllStructGetData($hTestStruct,1); Hier stürtzt AutoIt immer am ("AutoIt funktioniert nicht mehr"). Da ist es auch egal, welchen Wert ich bei iOverviewBuffers einsetze.
    MsgBox(0,"",$sTest)

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

    _Log("iOverviewBuffers: " & $iOverviewBuffers)
    _Log("iOverflow: " & $iOverflow)
    _Log("uiTriggeredAt: " & $uiTriggeredAt)
    _Log("iTriggered: " & $iTriggered)
    _Log("iAutoStop: " & $iAutostop)
    _Log("nValues: " & $nValues)

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

    EndFunc ;==>__PICO_Callback_MyGetOverviewBuffers

    [/autoit]

    Ich weiß, nicht ganz einfacher Stoff, aber ich wäre euch wirklich super dankbar, wenn mal jemand drüber schauen kann und mir eventuell den richtigen Weg zeigen kann, stehe hier grade leider ziemlich auf dem Schlauch :(
    Gruß und vielen Dank,
    Spider

  • Du musst beim DLLCallback auch ptr statt short als Typ angeben. Wenn ich die Doku richtig verstehe, dann sollte es so passen:

    [autoit]

    Global $hPICO_CallBackRegister = DllCallbackRegister("__PICO_Callback_MyGetOverviewBuffers", "none", "ptr;short;ulong;short;short;ulong")
    Global $gbBuffer_ChannelA = Binary(""), $gbBuffer_ChannelB = Binary("")

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

    Func __PICO_Callback_MyGetOverviewBuffers($ptrOverviewBuffers, $iOverflow, $uiTriggeredAt, $iTriggered, $iAutostop, $nValues)
    Local $tBuffers = DLLStructCreate("ptr[2]", $ptrOverviewBuffers)
    $gbBuffer_ChannelA &= DLLStructGetData(DLLStructCreate("byte[" & $nValues * 2 & "]", DLLStructGetData($tBuffers, 1, 1)), 1)
    $gbBuffer_ChannelB &= DLLStructGetData(DLLStructCreate("byte[" & $nValues * 2 & "]", DLLStructGetData($tBuffers, 1, 2)), 1)
    EndFunc ;==>__PICO_Callback_MyGetOverviewBuffers

    [/autoit]