Iczer

Structures with arrays of structures

6 posts in this topic

#1 ·  Posted

I need to pass some 2d autoit array to my self-written freebasic dll but cannot figure out how i should declare and fill structure containing array of structures (rows) from autoit side

;'==========================================================================================
Local $tagElement = "struct Element;ULONG iID;" & _
                                    "CHAR name[1024];" & _
                                    "WCHAR nameW[256];" & _
                                    "BOOLEAN changed;" & _
                                    "CHAR info[2048];" & _
                                    "INT State;" & _
                                    "UINT Color;" & _
                                    "HWND handle;" & _
                             "endstruct"
;'==========================================================================================
Local $tagDataArray = "struct;ULONG iCount;" & $tagElement & " element[256];endstruct"
;'==========================================================================================
$tDataArray  = DllStructCreate($tagDataArray )

ConsoleWrite("@error #0 = " & @error & @CRLF)
ConsoleWrite("---------------------" & @CRLF)

For $i = 1 to 8
    DllStructGetData ( $tDataArray.element($i), 1,5)
    ConsoleWrite("@error #" & $i & " = " & @error & @CRLF)

Next

ConsoleWrite("---------------------" & @CRLF)
;'==========================================================================================

 

Share this post


Link to post
Share on other sites



#2 ·  Posted

You need to repeat your structure and remove the names.

something like

mystruct="long;long;char[100];"

So then

myconcatenatedstructure=mystruct & mystruct & mystruct & mystruct

 

Saludos

Share this post


Link to post
Share on other sites

#3 ·  Posted

since creation of this structure :

Local $tagDataArray = "struct;ULONG iCount;" & $tagElement & " element[256];endstruct"

do not give any error, I hoped for errors in my method of access to resulting structure...

Share this post


Link to post
Share on other sites

#4 ·  Posted

if i try another way - arrays of elements in structure - it errorout on access ULong array element ( error 3 = Index out of range), but OK on Char array:

;'==========================================================================================
Local $iSize = 64
local $tagStructElementEX = "struct;ULONG iID[" & $iSize & "];CHAR Name[" & $iSize * 256 & "];endstruct"

ConsoleWrite("$tagStructElementEX = '" & $tagStructElementEX & "'" & @CRLF)

Local $t = DllStructCreate($tagStructElementEX)

ConsoleWrite("@error #0 = " & @error & @CRLF)
ConsoleWrite("---------------------" & @CRLF)

;'==========================================================================================

For $i = 1 to 3

    $t.iID($i) = $i
    ConsoleWrite("@error 1 #" & $i & " = " & @error & @CRLF)

    $t.Name(256 * $i) = "some strange name # " & $i
    ConsoleWrite("@error 2 #" & $i & " = " & @error & @CRLF)

    ConsoleWrite("---" & @CRLF)
Next

ConsoleWrite("---------------------" & @CRLF)
;'==========================================================================================

why?

Share this post


Link to post
Share on other sites

#5 ·  Posted

in the end combination of nameless "arrays" worked:

;'==========================================================================================
Local $iSize = 256
;'==========================================================================================
local $tagData = "struct;ULONG;"

$tagData &= _StringRepeat("ULONG;",$iSize)

$tagData &= _StringRepeat("CHAR[256];",$iSize)
$tagData &= _StringRepeat("WCHAR[256];",$iSize)

$tagData &= _StringRepeat("CHAR[512];",$iSize)
$tagData &= _StringRepeat("WCHAR[512];",$iSize)

$tagData &= _StringRepeat("CHAR[1024];",$iSize)
$tagData &= _StringRepeat("WCHAR[1024];",$iSize)

$tagData &= _StringRepeat("BOOLEAN;",$iSize)
$tagData &= _StringRepeat("CHAR[64];",$iSize)
$tagData &= _StringRepeat("CHAR[64];",$iSize)
$tagData &= _StringRepeat("INT;",$iSize)
$tagData &= _StringRepeat("CHAR[64];",$iSize)

$tagData &= _StringRepeat("INT;",$iSize)
$tagData &= _StringRepeat("CHAR[64];",$iSize)

$tagData &= _StringRepeat("HWND;",$iSize)
$tagData &= _StringRepeat("BYTE;",$iSize)
$tagData &= _StringRepeat("UINT;",$iSize)
$tagData &= _StringRepeat("BOOLEAN;",$iSize)
$tagData &= _StringRepeat("CHAR[64];",$iSize)

$tagData &= "endstruct"

ConsoleWrite("$tagData = '" & $tagData & "'" & @CRLF)

Local $tData = DllStructCreate($tagData)

ConsoleWrite("@error #0 = " & @error & @CRLF)
ConsoleWrite("---------------------" & @CRLF)

;'==========================================================================================

DllStructSetData($tData,1,8)

For $i = 1 to 256


    DllStructSetData($tData,1+$i,$i)
    if @error Then ConsoleWrite("@error 1 #" & $i & " = " & @error & @CRLF)

    DllStructSetData($tData,1+$i+$iSize*2,"some strange name # " & $i)
    if @error Then ConsoleWrite("@error 2 #" & $i & " = " & @error & "   Name = " & DllStructGetData($tData,1+$i+$iSize*2) & @CRLF)

    ConsoleWrite("iID = " & DllStructGetData($tData,1+$i) & "   Name = " & DllStructGetData($tData,1+$i+$iSize*2) & @CRLF)
Next

ConsoleWrite("---------------------" & @CRLF)
;'==========================================================================================

 

but only direct pass worked - if I try to pass this structure by pointer, i get crash in dll...

DllStructSetData($tDispatchData, "pData", DllStructGetPtr ($tData) )

is there a some necessary requirements to pass data by pointer?

Share this post


Link to post
Share on other sites

#6 ·  Posted

Hello. You can do something like this.

Local $sTagStruct="dword;wchar[512];char[512];int;"
Local $tStruct=DllStructCreate( $sTagStruct &  $sTagStruct)
ConsoleWrite("IsDllStruct($tStruct)= " & IsDllStruct($tStruct) & @CRLF)


;My Struct[0]
DllStructSetData($tStruct,1,10);$sTagStruct[0].dword=10
DllStructSetData($tStruct,2,"My WString WCHAR [0]");$sTagStruct[0].wchar="My WString WCHAR [0]"
DllStructSetData($tStruct,3,"My String CHAR [0]");$sTagStruct[0].char="My String CHAR [0]"
DllStructSetData($tStruct,4,20);$sTagStruct[0].int=20

;My Struct[1]
DllStructSetData($tStruct,5,15);$sTagStruct[1].dword=15
DllStructSetData($tStruct,6,"My WString WCHAR [1]");$sTagStruct[1].wchar="My WString WCHA [1]"
DllStructSetData($tStruct,7,"My String CHAR [1]");$sTagStruct[1].char="My String CHAR [1]"
DllStructSetData($tStruct,8,25);$sTagStruct[1].int=25

 

In your dll something like this:

typedef struct MyStruct {
    DWORD MyWord;
    WCHAR MyWChar[512];
    CHAR  MyChar[512];
    int   MyInt;
} MyStruct, *PMyStruct;

 

your Function parameter could be something like this:

MyFunction(struct MyStruct * Struct)

Would be great that you pass the array bound to avoid out of Memory.

 

Then you can access like this:

Struct[0].MyWord 
 Struct[0].MyWChar
 Struct[0].MyChar
 Struct[0].MyInt



 Struct[1].MyWord
 Struct[1].MyWChar
 Struct[1].MyChar
 Struct[1].MyInt

 

Saludos

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now