Arrays als Dll-Elemente

    • Offizieller Beitrag

    Da ich nicht jeden Tag mit den Dll arbeite, bin ich da auch nicht so fit. Insbesondere, wenn Dll's Arrays als Parameter erwarten, ist dies manchmal etwas verzwickt. :whistling:
    Auf diesem Wege möchte ich gleich mal einen großen Dank an progandy loswerden, der mit seinem komplexen Wissen immer hilfreich zur Seite steht und ohne den dieses hier auch nicht entstanden wäre. :thumbup:

    Ich habe ein paar Funktionen geschrieben, die das Erstellen von Dll-Array vereinfachen und ebenfalls Funktionen zum Auslesen von Werten, die man i.A. dann eher zum Debuggen benötigt.
    Ich hoffe, dass es für euch auch brauchbar ist.

    Beispiel
    [autoit]

    #include <StructureConstants.au3>
    #include 'DLL_Arrays.au3' ; <== hier ggf. anpassen, bei mir sind beide Dateien im selben Ordner
    ;==================================================================================================
    ; Struktur: Pointer-Array
    ;==================================================================================================

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

    ; === Erstellen Integer Array
    Local $aPtrInt = _PtrArray_Create('int', 10)

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

    ; === Werte setzen
    _PtrArray_SetData($aPtrInt, '10,20,30,40,50,60,70,80,90,100', ',')

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

    ; === Auslesen alle Werte in Console
    ConsoleWrite('Alle Werte als String, $aPtrInt:' & @CRLF)
    _PtrArray_GetData($aPtrInt, 'int')

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

    ; === Auslesen eines Wertes in Console
    ConsoleWrite(@CRLF & 'Wert 7 $aPtrInt:' & @CRLF)
    _PtrArray_GetData($aPtrInt, 'int', 7)

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

    ; === Auslesen alle Werte in ein Array
    ConsoleWrite(@CRLF & 'Alle Werte als Array, $aPtrInt:' & @CRLF)
    Local $aRet = _PtrArray_GetData($aPtrInt, 'int', -1, 2)
    For $i = 0 To UBound($aRet) -1
    ConsoleWrite($aRet[$i] & @CRLF)
    Next
    ;==================================================================================================

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

    ; === Erstellen Zeichenkette Array
    Local $aPtrChar = _PtrArray_Create('char[128]', 5)

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

    ; === Werte setzen
    _PtrArray_SetData($aPtrChar, 'Anna,Lena,Magda,Isabell,Juliane', ',')

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

    ; === Auslesen alle Werte in Console
    ConsoleWrite(@CRLF & 'Alle Werte als String, $aPtrChar:' & @CRLF)
    _PtrArray_GetData($aPtrChar, 'char[128]')

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

    ; === Auslesen eines Wertes in Console
    ConsoleWrite(@CRLF & 'Wert 3 $aPtrChar:' & @CRLF)
    _PtrArray_GetData($aPtrChar, 'char[128]', 3)

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

    ; === Auslesen alle Werte in ein Array
    ConsoleWrite(@CRLF & 'Alle Werte als Array, $aPtrChar:' & @CRLF)
    $aRet = _PtrArray_GetData($aPtrChar, 'char[128]', -1, 2)
    For $i = 0 To UBound($aRet) -1
    ConsoleWrite($aRet[$i] & @CRLF)
    Next

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

    ;==================================================================================================
    ; Struktur: Byte-Array
    ;==================================================================================================

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

    ; === Erstellen Array mit 3 RECT-Strukturen als Elementen
    ; Returnwert: ein echtes Array, $aByte[0] enthält die Variable, die an einen Dll-Aufruf zu übergeben wäre
    Local $aByteRECT = _ByteArray_Create($tagRECT, 3)

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

    ; === Strukturen befüllen (für RECT mit API-Func: SetRect)
    If Not _WinAPI_SetRect($aByteRECT[1], 20, 30, 200, 300) Then ConsoleWrite('Error: ' & @error & @CRLF)
    If Not _WinAPI_SetRect($aByteRECT[2], 40, 50, 240, 350) Then ConsoleWrite('Error: ' & @error & @CRLF)
    If Not _WinAPI_SetRect($aByteRECT[3], 60, 70, 260, 370) Then ConsoleWrite('Error: ' & @error & @CRLF)

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

    ; === Auslesen in Console
    ConsoleWrite(@CRLF & 'Alle Werte der Strukturen im Byte-Array:' & @CRLF)
    For $i = 1 To 3
    ConsoleWrite('RECT ' & $i & ':' & @CRLF)
    _Struct_GetValue($aByteRECT[$i])
    Next

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

    ;===============================================================================
    ; Function Name: _WinAPI_SetRect(ByRef $tRECT, $X1, $Y1, $X2, $Y2)
    ; Description: Befüllt eine RECT-Struktur in einem Aufruf mit Werten
    ; Parameter(s): $tRECT RECT-Struktur
    ; $X1, $Y1, $X2, $Y2 Werte des Rectangle
    ; Return Value(s): Erfolg > 0
    ; Fehler 0 set @error
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _WinAPI_SetRect(ByRef $tRECT, $X1, $Y1, $X2, $Y2)
    Local $ret = DllCall("user32", 'long', 'SetRect', 'ptr', DllStructGetPtr($tRECT), 'long', $X1, 'long', $Y1, 'long', $X2, 'long', $Y2)
    If @error > 0 Then Return SetError(1,@error,0)
    Return $ret[0]
    EndFunc ;==>_WinAPI_SetRect

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

    #include-once
    ;===============================================================================
    ; Function Name: _ByteArrayCreate($sSTRUCT, $iELEMENTS=2)
    ; Description: Erstellt eine Bytearray-Struktur
    ; $aBYTE[0] enthält die Variable, die an einen Dll-Aufruf zu übergeben wäre
    ; Parameter(s): $sSTRUCT String der Struktur
    ; $iELEMENTS Anzahl der Elemente des Bytearray
    ; Return Value(s): das erstellte Bytearray
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _ByteArray_Create($sSTRUCT, $iELEMENTS=2)
    Local $SIZE = DllStructGetSize(DllStructCreate($sSTRUCT, 1))
    Local $aBYTE[$iELEMENTS +1]
    $aBYTE[0] = DllStructCreate('byte[' & $SIZE *$iELEMENTS & "]")
    Local $ptr = DllStructGetPtr($aBYTE[0])
    For $i = 0 To $iELEMENTS -1
    $aBYTE[$i+1] = DllStructCreate($sSTRUCT, $ptr + $i*$SIZE)
    Next
    Return $aBYTE
    EndFunc ;==>_ByteArray_Create

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

    ;===============================================================================
    ; Function Name: _PtrArray_Create($sSTRUCT, $iELEMENTS=2)
    ; Description: Erstellt eine Pointerarray-Struktur
    ; Parameter(s): $sSTRUCT String der Struktur
    ; $iELEMENTS Anzahl der Elemente des Pointerarray
    ; Return Value(s): das erstellte Pointerarray
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _PtrArray_Create($sSTRUCT, $iELEMENTS=2)
    Local $struct = 'ptr[' & $iELEMENTS & '];'
    For $i = 1 To $iELEMENTS
    $struct &= $sSTRUCT & ';'
    Next
    Local $aPTR = DllStructCreate($struct)
    For $i = 1 To $iELEMENTS
    DllStructSetData($aPTR, 1, DllStructGetPtr($aPTR, $i+1), $i)
    Next
    Return $aPTR
    EndFunc ;==>_PtrArray_Create

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

    ;===============================================================================
    ; Function Name: _PtrArray_SetData(ByRef $tSTRUCT, $sDATA, $sDELIM=Default)
    ; Description: Füllt ein Pointerarray mit Daten
    ; Parameter(s): $tSTRUCT die Pointerstruktur
    ; $sDATA die zu setzenden Daten, getrennt durch $sDELIM
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _PtrArray_SetData(ByRef $tSTRUCT, $sDATA, $sDELIM=Default)
    If IsKeyword($sDELIM) Then $sDELIM = Opt('GUIDataSeparatorChar')
    Local $aData = StringSplit($sDATA, $sDELIM)
    For $i = 1 To $aData[0]
    If $aData[$i] = '' Then ContinueLoop
    DllStructSetData($tSTRUCT, $i+1, $aData[$i])
    Next
    EndFunc ;==>_PtrArray_SetData

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

    ;===============================================================================
    ; Function Name: _PtrArray_GetData(ByRef $aPTR, $sStructType, $iElements=-1, $iRetType=0, $sDelim=Default)
    ; Description: Einen od. alle Werte eines Pointerarray ausgeben, (in Console, String, Array),
    ; verweisende Pointer werden als 'Pointer' ausgegeben
    ; Parameter(s): $aPTR das Pointerarray
    ; $sStructType String mit dem Typ der verwendeten Struktur
    ; $iElements 1-basierter Index des zu lesenden Elements, -1(Standard) = alle
    ; $iRetType Rückgabe als: 0=Console (Standard), 1=Trennzeichenbasierter String, 2=Array
    ; $sDelim Trennzeichen, mit -1 od. Default Zeichen von Opt('GUIDataSeparatorChar')
    ; Return Value(s): Gelesene Daten in gewähltem Rückgabetyp
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _PtrArray_GetData(ByRef $aPTR, $sStructType, $iElements=-1, $iRetType=0, $sDelim=Default)
    Local $sOut = '', $iCount = 1, $structPtr, $currPtr, $structRead
    If IsKeyword($sDelim) Or $sDelim = -1 Then $sDelim = Opt('GUIDataSeparatorChar')
    While True
    DllStructGetData($aPTR, 1, $iCount)
    If @error Then ExitLoop
    $iCount += 1
    WEnd
    $structPtr = DllStructCreate("ptr[" & $iCount -1 & "];", DllStructGetPtr($aPTR, 1))
    If $iElements < 1 Then
    For $i = 1 To $iCount -1
    $currPtr = DllStructGetData($structPtr, 1, $i)
    $structRead = DllStructCreate($sStructType, $currPtr)
    $sRead = DllStructGetData($structRead, 1)
    If IsPtr($sRead) Then $sRead = 'Pointer'
    $sOut &= $sRead & $sDelim
    Next
    Else
    $currPtr = DllStructGetData($structPtr, 1, $iElements)
    $structRead = DllStructCreate($sStructType, $currPtr)
    $sRead = DllStructGetData($structRead, 1)
    If IsPtr($sRead) Then $sRead = 'Pointer'
    $sOut &= $sRead & $sDelim
    EndIf
    Switch $iRetType
    Case 0 ; ==> console
    Return ConsoleWrite(StringTrimRight($sOut, StringLen($sDelim)) & @CRLF)
    Case 1 ; ==> delimited string
    Return StringTrimRight($sOut, StringLen($sDelim))
    Case Else ; ==> array
    Return StringSplit(StringTrimRight($sOut, StringLen($sDelim)), $sDelim, 3)
    EndSwitch
    EndFunc ;==>_PtrArray_GetData

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

    ;===============================================================================
    ; Function Name: _StructGetValue(ByRef $tSTRUCT, $iRetType=0, $sDelim=-1)
    ; Description: Ausgabe aller Werte einer Struktur (in Console, String, Array),
    ; verweisende Pointer werden als 'Pointer' ausgegeben
    ; Parameter(s): $tSTRUCT Struktur aus der die Daten gelesen werden
    ; $iRetType Rückgabe als: 0=Console (Standard), 1=Trennzeichenbasierter String, 2=Array
    ; $sDelim Trennzeichen, mit -1 od. Default Zeichen von Opt('GUIDataSeparatorChar')
    ; Return Value(s): Gelesene Daten in gewähltem Rückgabetyp
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _Struct_GetValue(ByRef $tSTRUCT, $iRetType=0, $sDelim=-1)
    Local $sOut = '', $sRead, $i = 1
    If IsKeyword($sDelim) Or $sDelim = -1 Then $sDelim = Opt('GUIDataSeparatorChar')
    While True
    $sRead = DllStructGetData($tSTRUCT, $i)
    If @error Then ExitLoop
    If IsPtr($sRead) Then $sRead = 'Pointer'
    $sOut &= $sRead & $sDelim
    $i += 1
    WEnd
    Switch $iRetType
    Case 0 ; ==> console
    Return ConsoleWrite(StringTrimRight($sOut, StringLen($sDelim)) & @CRLF)
    Case 1 ; ==> delimited string
    Return StringTrimRight($sOut, StringLen($sDelim))
    Case Else ; ==> array
    Return StringSplit(StringTrimRight($sOut, StringLen($sDelim)), $sDelim, 3)
    EndSwitch
    EndFunc ;==>_Struct_GetValue

    [/autoit]