weirddave Posted September 20, 2016 Share Posted September 20, 2016 I want to construct a data payload based on a whole load of things which set the individual bits in the bytes. Ideally I'd like to access the bytes in the form: $TxData [ $ByteNo ] Followed by: UDPSend ( $TxSocket, $TxData ) How do I specify $TxData[] as an array of bytes? Link to comment Share on other sites More sharing options...
RTFC Posted September 20, 2016 Share Posted September 20, 2016 (edited) DLLstructCreate assigns a struct to a variable, which can contain lots of bytes. However if you're using fewer than 33 flags, I would just store a single (32-bit) integer in a variable and set its individual bits with $var=BitOr($var,2^<yourbit>). Edited September 20, 2016 by RTFC typo My Contributions and Wrappers Spoiler BitMaskSudokuSolver BuildPartitionTable CodeCrypter CodeScanner DigitalDisplay Eigen4AutoIt FAT Suite HighMem MetaCodeFileLibrary OSgrid Pool RdRand SecondDesktop SimulatedAnnealing Xbase I/O Link to comment Share on other sites More sharing options...
weirddave Posted September 20, 2016 Author Share Posted September 20, 2016 Thanks for the replay I shall take a look at DLLstructCreate, I have 54 bytes (some are values, others are flag bits) at the moment and that is likely to increase. Had a look, would: $TxData = DLLStructCreate ( "struct; byte myTxData[54] ;endstruct" ) do the trick? Set the bytes like so: DllStructSetData ( $TxData, myTxData, n ) where 'n' is the byte I want to set. I assume this starts at 0? When receiving packets, what should I do to read individual bytes? Link to comment Share on other sites More sharing options...
RTFC Posted September 21, 2016 Share Posted September 21, 2016 See DllstructGetData. The index is base-1 though, and refers to the entire chunk of bytes you defined. If you want 54 separately addressable bytes you need to define them individually (byte;byte;byte...). Then you could also name each flag individually (byte flag1; byte flag2...). But you're still wasting bandwidth by a factor 8 this way; I would define two dwords or one int64 instead (= 64 bit flags), and set/test/reset their individual bits (and not use entire bytes). Up to you, of course. My Contributions and Wrappers Spoiler BitMaskSudokuSolver BuildPartitionTable CodeCrypter CodeScanner DigitalDisplay Eigen4AutoIt FAT Suite HighMem MetaCodeFileLibrary OSgrid Pool RdRand SecondDesktop SimulatedAnnealing Xbase I/O Link to comment Share on other sites More sharing options...
weirddave Posted September 21, 2016 Author Share Posted September 21, 2016 The flags are grouped into bytes already, there's only a few spare bits in those 54 bytes. I can see how to use DllstructGetDat, but how do I get the data into it from UDPRECV()? I will probably want to check the IP address so my command was going to be along the lines of: $sReceived = UDPRECV( $RxSocket, $RxDataLength, 3 ) The autoit examples really aren't helping me Link to comment Share on other sites More sharing options...
RTFC Posted September 21, 2016 Share Posted September 21, 2016 (edited) 2 hours ago, weirddave said: The flags are grouped into bytes already That's a lot of flags! Yeah, the examples tend to show the most basic usage only. Having had to write several Help docs for my own software, I can relate to the inclination to leave it at that. There's some user-generated content on UDP on the forum (google: "site:autoitscript.com UDP"), or you could study my fairly densely annotated Pool environment (link in signature) for example, which does UDP (amongst a few other things). It's neither small nor simple though, so maybe you'd best study some of the other examples instead/first. Edited September 21, 2016 by RTFC My Contributions and Wrappers Spoiler BitMaskSudokuSolver BuildPartitionTable CodeCrypter CodeScanner DigitalDisplay Eigen4AutoIt FAT Suite HighMem MetaCodeFileLibrary OSgrid Pool RdRand SecondDesktop SimulatedAnnealing Xbase I/O Link to comment Share on other sites More sharing options...
weirddave Posted September 21, 2016 Author Share Posted September 21, 2016 A lot of the data is just values, there's only about 40 flags The 'other end' will be an arduino style device (based on the Due micro), connected to a FPGA which in turn communicates with a bunch of other stuff, hence all the data and flags. I took a little look at Pool, I think I need to keep it light, I'm aiming for 1ms loop times. 'This end' will be replaced with Arduino style hardware as well, the purpose of the autoit code is to emulate either end to help debug it I shall see what google throws my way... Cheers. Link to comment Share on other sites More sharing options...
weirddave Posted September 22, 2016 Author Share Posted September 22, 2016 I've managed to send some data using: $TxStruct = String("struct;byte myTxData[54];endstruct") $TxData = DLLStructCreate ( $TxStruct ) $BinTxData = DLLStructGetData($TxData, "myTxData") UDPSend($TxSocket, $BinTxData) Is that the right way to do it? If I were to create a more meaningful structure, such as: $TxStruct = String("struct;byte flags;byte data;endstruct") how would I send the whole structure? Google really isn't finding the information I want Link to comment Share on other sites More sharing options...
funkey Posted September 22, 2016 Share Posted September 22, 2016 Global $tData = DllStructCreate("byte myTxData[54]") Global $tMeaningfulStruct = DllStructCreate("byte flags[6];byte data[6]", DllStructGetPtr($tData)) ; point to the data struct DllStructSetData($tMeaningfulStruct, "flags", _SetBit(0, 0), 2) ; set bit 0 of second flag byte DllStructSetData($tMeaningfulStruct, "flags", _SetBit(0, 1), 3) ; set bit 1 of third flag byte DllStructSetData($tMeaningfulStruct, "data", 0xff, 2) ; set 0xff to second data byte Global $bData = DllStructGetData($tData, "myTxData") ConsoleWrite($bData & @CRLF) Func _SetBit($bVal, $iPos) Return BitOR($bVal, 2^$iPos) EndFunc argumentum and weirddave 2 Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
weirddave Posted September 23, 2016 Author Share Posted September 23, 2016 I'm speechless, thanks for that, you've helped massively. If I have received a block of data, can I use the same method? Global $tDataRx = DllStructCreate("byte myRxData[4]") $sReceived = UDPRECV($RxSocket, $RxDataLength, $RxUDPStyle); this contains the data block (4 bytes) $tMeaningfulStructRx = DllStructCreate("byte flagsRx[2];byte dataRx[2]", DllStructGetPtr($sReceived)) ; point to the data struct $temp = DllStructGetData($tMeaningfulStructRx, "dataRx",1) ; get the first data byte msgbox(0,"",$temp) Link to comment Share on other sites More sharing options...
weirddave Posted September 23, 2016 Author Share Posted September 23, 2016 I think I have that all wrong Global $tDataRx = DllStructCreate("byte myRxData[4]") $tMeaningfulStructRx = DllStructCreate("byte flagsRx[2];byte dataRx[2]", DllStructGetPtr($tDataRx)) ; point to the data struct $sReceived = UDPRECV($RxSocket, $RxDataLength, $RxUDPStyle); this contains the data block (4 bytes) DllStructSetData($tDataRx, "myRxData", $sReceived) ; $temp = DllStructGetData($tMeaningfulStructRx, "dataRx",1) ; get the first data byte msgbox(0,"",$temp) I think this is the right way to do it. Hopefully I can write a piece of test code to prove it Link to comment Share on other sites More sharing options...
funkey Posted September 23, 2016 Share Posted September 23, 2016 Looks good. weirddave 1 Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
weirddave Posted September 23, 2016 Author Share Posted September 23, 2016 I've created a file with all the byte names in which I read in to create the struct so that I can change things without diving into the code. This appears to be working but has the side effect of creating the 'meaningful' struct first then using its pointer for the packet data struct (I need the length from the meaningful struct before I can create the packet struct). I think this works because the structs are 'real' and not some autoit version of reality, is this correct? Link to comment Share on other sites More sharing options...
funkey Posted September 23, 2016 Share Posted September 23, 2016 You are right. It does not matter what structure points to the other one. DllStructCreate without pointer allocates the real memory. DllStructCreate with pointer points to the real memory location allocated first. weirddave 1 Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now