Eine kleine Funktion, welche schon längere Zeit bei mir liegt und mir beim Umgang mit Dll-Strukturen schon öfters mal geholfen hat.
Ich denke die Funktion könnte auch für den ein oder andere nützlich sein:
AutoIt
#include-once
#include <Array.au3>
; die Strukturdefinition
Local $sStructStr = "Align 16;Short Albi;byte;hwnd;char;align 8;byte;short[2];dword;byte;short;byte;int64;char[9];int64;byte;" & _
"byte;ptr;char;double;short;wchar[3];byte;float;byte;uint_ptr;byte;char buffer[128];int;byte[13];word 2bytes;handle isptr;hwnd isalsoptr;" & _
"boolean isbyte[2];bool isint;dword_ptr;long_ptr;ulong_ptr;lparam;wparam;lresult;byte;"
; Struktur anhand der Definition erzeugen
Local $stStruct = DllStructCreate($sStructStr)
DllStructSetData($stStruct, 12, "Test")
; Konvertierung der Struktur in ein Array
Global $aArray = _DllStruct2Array($sStructStr, $stStruct)
; Ausgabe des Arrays
_ArrayDisplay($aArray, "DllStruct", "" , 64, Default, "Index|Name|Typ|Arraygröße|Wert|Größe|Offset|Pointer")
; #FUNCTION# ======================================================================================
; Name ..........: _DllStruct2Array()
; Description ...: converts a DllStruct variable to a 2D array based on its structure string
; Syntax ........: _DllStruct2Array($tagStruct, ByRef $tStruct)
; Parameters ....: $tagStruct - A string representing the structure to create (like "Struct" in DllStructCreate)
; ByRef $tStruct - a structure variable with the structure described in $tagStruct
; Return values .: Success: 2D-Array with the following structure:
; |[[index N, name N, type N, arraysize N, value N, size N, offset N, isPointer N], [...], ...]
; Failure: Null and set @error to:
; |@error = 1: $tStruct is not a dll struct variable
; Author ........: aspirinjunkie
; Modified ......: 2022-07-13
; Remarks .......: for LRESULT/[LW]PARAM/PTR/HWND/HANDLE value is pointer address,
; for xxx_PTR value is taken from the address where the pointer points,
; for [W]CHAR value is a string if element is an [W]CHAR-array, otherwise the numerical value
; Link ..........: x
; Example .......: Yes
; #include <Array.au3>
; $tagSTRUCT1 = "struct;int var1;byte var2;uint var3;char var4[128];endstruct"
; Local $tSTRUCT1 = DllStructCreate($tagSTRUCT1)
; $aStructInfo = _DllStruct2Array($tagSTRUCT1, $tSTRUCT1)
; _ArrayDisplay($aStructInfo, "DllStruct", "" , 64, Default, "Index|Name|Typ|Arraygröße|Wert|Größe|Offset|Pointer")
; =================================================================================================
Func _DllStruct2Array($tagStruct, ByRef $tStruct)
Local Enum $eIndex, $eName, $eType, $eArraySize, $eValue, $eSize, $eOffset, $eIsPointer
Local $aRegEx, $sTmp
Local $aElements = StringSplit($tagStruct, ";", 3)
If Not IsDllStruct($tStruct) Then Return SetError(1, 0, Null)
Local $aArray[UBound($aElements)][8], $iC = 0, $tTmp, $iBaseAddress = DllStructGetPtr($tStruct)
For $tagElement In $aElements
$aArray[$iC][$eArraySize] = ""
$aArray[$iC][$eIsPointer] = ""
; a data element
$aRegEx = StringRegExp($tagElement, "(?i)^\h*(BOOL(?>EAN)?|BYTE|(?>U|W)?CHAR|DOUBLE|D?WORD(?>_PTR)?|FLOAT|HANDLE|HWND|U?INT(?>64|_PTR)?|(?>L|W)PARAM|LRESULT|PTR|U?SHORT|U?LONG(?>_PTR)?)", 3)
If @error Then ContinueLoop ; no "align", "struct", "endstruct" etc. handling - only elements
; element data type
$aArray[$iC][$eType] = $aRegEx[0]
; element index
$aArray[$iC][$eIndex] = $iC + 1
; element offset
$aArray[$iC][$eOffset] = Int(DllStructGetPtr($tStruct, $aArray[$iC][$eIndex]) - $iBaseAddress)
; pointer type?
$sTmp = StringStripWS(StringTrimLeft($tagElement, StringLen($aArray[$iC][$eType])), 2)
If StringInStr($sTmp, "*", 1) Then $aArray[$iC][$eIsPointer] = True
; Array defined?
$aRegEx = StringRegExp($sTmp, "\[\h*(\d+)\h*\]", 3)
If Not @error Then $aArray[$iC][$eArraySize] = Int($aRegEx[0])
; element name
$aRegEx = StringRegExp($sTmp, "(\w+)\h*(?>$|\[)", 3)
If Not @error Then $aArray[$iC][$eName] = $aRegEx[0]
; element size
$aArray[$iC][$eSize] = -1
If StringRegExp($aArray[$iC][$eType], "(?i)^(BOOLEAN?|BYTE|U?CHAR)$") Then $aArray[$iC][$eSize] = 1
If StringRegExp($aArray[$iC][$eType], "(?i)^(WCHAR|U?SHORT|WORD)$") Then $aArray[$iC][$eSize] = 2
If StringRegExp($aArray[$iC][$eType], "(?i)^(U?INT|U?LONG|BOOL|DWORD|FLOAT)$") Then $aArray[$iC][$eSize] = 4
If StringRegExp($aArray[$iC][$eType], "(?i)^(U?INT64|DOUBLE)") Then $aArray[$iC][$eSize] = 8
If StringRegExp($aArray[$iC][$eType], "(?i)^(.+\_PTR|LRESULT|[LW]PARAM|PTR|HWND|HANDLE)") Then ; pointer type
$aArray[$iC][$eIsPointer] = True
$aArray[$iC][$eSize] = @AutoItX64 ? 8 : 4
EndIf
If $aArray[$iC][$eArraySize] > 1 Then $aArray[$iC][$eSize] *= $aArray[$iC][$eArraySize]
; element value
If $aArray[$iC][$eIsPointer] Then ; pointer type
If StringRegExp($aArray[$iC][$eType], "(?i)\_PTR$") Then ; pointer to integer values
$tTmp = DllStructCreate(StringTrimRight($aArray[$iC][$eType], 4), DllStructGetPtr($tStruct, $aArray[$iC][$eIndex]))
$aArray[$iC][$eValue] = DllStructGetData($tTmp, 1)
$tTmp = Null
Else ; normal unspecific pointer
$aArray[$iC][$eValue] = DllStructGetData($tStruct, $aArray[$iC][$eIndex])
EndIf
ElseIf $aArray[$iC][$eArraySize] > 0 Then ; array elements
If StringRegExp($aArray[$iC][$eType], "(?i)W?CHAR") Then ; char array (a string)
$aArray[$iC][$eValue] = DllStructGetData($tStruct, $aArray[$iC][$eIndex])
Else ; normal element array
Local $aTmp[$aArray[$iC][$eArraySize]]
For $i = 0 To $aArray[$iC][$eArraySize] - 1
$aTmp[$i] = DllStructGetData($tStruct, $aArray[$iC][$eIndex], $i + 1)
Next
$aArray[$iC][$eValue] = $aTmp
EndIf
Else
$aArray[$iC][$eValue] = DllStructGetData($tStruct, $aArray[$iC][$eIndex])
EndIf
$iC += 1
Next
ReDim $aArray[$iC][UBound($aArray, 2)]
Return SetExtended(DllStructGetSize($tStruct), $aArray)
EndFunc ;==>_DllStruct2Array
Alles anzeigen