BlackFlag 0 Posted June 30, 2021 Share Posted June 30, 2021 I seem to have two modes when using Autoit. No problems what-so-ever most of the time or being completely baffled over something that seems to be easy. Luckily, the baffled part only seems happens once every two years or so. What I am trying to do. I have a file that includes a vessel name and part of its assigned serial number. Reduced, this is what I am using: $whatthe=FileOpen("C:\QUAD Manager Accounts\__ ADVANTAGE\__ ADVANTAGE.128",16) $readthefile=FileRead($whatthe) $apple=BinaryToString($readthefile,1) MsgBox(1,"Hope",$apple) $testtxt=fileopen("C:\QUAD Manager Accounts\__ ADVANTAGE\__ ADVANTAGE.test",2) FileWrite($testtxt,$apple) When I run this, it does read return the vessel name (in this case the good ship F/V Advantage) but never the serial number. I am assuming that I am not parsing the file correctly but I cannot figure out how to do it. Link to post Share on other sites
Nine 1,501 Posted June 30, 2021 Share Posted June 30, 2021 Upload the source file so we can take a look Not much of a signature but working on it... Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search content in au3 files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector GIF Animation (cached) Screen Scraping Link to post Share on other sites
BlackFlag 0 Posted June 30, 2021 Author Share Posted June 30, 2021 Find it attached. The name is __Advantage and the serial number should be (I think, the vessel sank in 2010 and the paper file has been archived) 285 __ ADVANTAGE.128 Link to post Share on other sites
TheXman 565 Posted July 1, 2021 Share Posted July 1, 2021 (edited) Since you didn't provide the record layout of the binary data, which would ordinarily be required, the script below makes the following assumptions: The name of the vessel is a null-terminated char string, starting at offset 0x00 (0), and is no longer than 32 bytes. The serial number is a little-endian uint (32-bit unsigned integer), starting at offset 0x20 (32) If the script doesn't work with other records/files, then you need to supply a record layout or make the necessary modifications yourself. Finally, this is just one of many ways that it could be done. #include <Constants.au3> example() Func example() Local $hFile Local $tByteBuffer = DllStructCreate("byte data[128]"), _ $tRecord = DllStructCreate("char vessel[32]; uint serialNo", DllStructGetPtr($tByteBuffer)) ;Open the file $hFile = FileOpen("__ ADVANTAGE.128", $FO_BINARY) If $hfile = -1 Then Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "ERROR", "Unable to open file") ;Read the binary data from the file & close the file $tByteBuffer.data = FileRead($hfile) FileClose($hfile) ;Display fields ConsoleWrite("Vessel = " & $tRecord.vessel & @CRLF) ConsoleWrite("Serial = " & $tRecord.serialNo & @CRLF) EndFunc Console output: Vessel = __ ADVANTAGE Serial = 285 Edited July 1, 2021 by TheXman Changed serial number from a word to a uint JockoDundee 1 About Me | CryptoNG UDF - Cryptography API: Next Gen | jq UDF - Powerful and Flexible JSON Processor| HttpApi UDF - HTTP Server API If you want better answers, learn how to ask better questions or read How to Ask Questions in a Technical Forum. Link to post Share on other sites
JockoDundee 633 Posted July 1, 2021 Share Posted July 1, 2021 @TheXman, your use of DllStructs without any corresponding DllCall is edifying.* Curious, apart from using them with DllCalls or to sort a binary overlay (as in this case), do you find it useful to create structs just to use as standalone data structures? Are there any downsides to that? *Apology to BlackFlag for the off-topic Code hard, but don’t hard code... Link to post Share on other sites
TheXman 565 Posted July 1, 2021 Share Posted July 1, 2021 (edited) I don't associate DllStructs with DllCalls. I only associate DllStructs with binary data/records. If I need to work with well-defined binary data/records, then I usually use DllStructs. Sometimes I will just parse out the fields with BinaryMid() functions, but I find it cleaner and easier to maintain structs. At the moment, I can't think of any downsides to using structs to work with binary data. On the other hand, I can think of at least a couple on downsides to using BinaryMid() instead of DllStructs, which mostly involve having to calculate and manage offsets as well as the additional functions necessary to do some of the data type conversions. I forgot to mention that I also think of DllStructs if I need to work with data pointers. Edited July 1, 2021 by TheXman JockoDundee 1 About Me | CryptoNG UDF - Cryptography API: Next Gen | jq UDF - Powerful and Flexible JSON Processor| HttpApi UDF - HTTP Server API If you want better answers, learn how to ask better questions or read How to Ask Questions in a Technical Forum. Link to post Share on other sites
RTFC 441 Posted July 1, 2021 Share Posted July 1, 2021 Agree with @TheXman, DllStructs are absolutely the way to access and (re)interpret binary data. However, an important caveat is the alignment of its data members. By default, AutoIt uses 8 bytes with #pragma pack directive, which can produce all manner of unexpected misinterpretations due to undesired/unexpected shifts (note that member type size may change depending on processor architecture, e.g., ptrs and handles in x86 vs x64). To prevent this, I always explicitly align in any struct definition (simply add "align #;" prior to the first data member definition, with # = number of bytes to align each member on), which serves as a note to self (and others reading the code) and may significantly speed up I/O when dealing with large binary data sets. JockoDundee and TheDcoder 2 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 post Share on other sites
JockoDundee 633 Posted July 1, 2021 Share Posted July 1, 2021 @TheXman, @RTFC: What you guys are saying makes sense, thx. OTOH, I’m not sure I’ve made myself totally clear. Basically because you are referring to “interpret[ing]” and “well-defined records” etc. And I agree there. But I am also talking about just for internal variable storage - as a way to compensate for there being no direct support for structs in AutoIt. tl dr; I just want to use them so that I can dot notation in my program - and not necessarily as an interface to some predefined binary record. Does that make sense? Code hard, but don’t hard code... Link to post Share on other sites
RTFC 441 Posted July 1, 2021 Share Posted July 1, 2021 (edited) 4 hours ago, JockoDundee said: Does that make sense? Sure. One way to think of structs is as a single database record with named fields containing a fixed-order, fixed-width combination of desired variable types. Dot notation would be one way of accessing the contents of a specific field (DllStructGet/SetData being another). I guess I was thinking more of (numeric) offset-based access from a pointer to the struct. Another cool feature of structs is that any part (or the entire struct) can be remapped (by parsing the 2nd, optional ptr parameter (obtained with DllStructGetPtr) to a second DllStructCreate call) using a different struct definition, which can for example be used to achieve the equivalent of reinterpret_cast<new type> in C++. Edited July 1, 2021 by RTFC JockoDundee 1 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 post Share on other sites
JockoDundee 633 Posted July 1, 2021 Share Posted July 1, 2021 4 hours ago, RTFC said: Another cool feature of structs is that any part (or the entire struct) can be remapped… Much like removable drawers in an IKEA wardrobe RTFC 1 Code hard, but don’t hard code... Link to post Share on other sites
BlackFlag 0 Posted July 2, 2021 Author Share Posted July 2, 2021 TheXman Thank you, I plugged it into the program I was writing and it worked like a charm. I'll spend a couple of days next week understanding how it works. I have two or three other projects that DllStructCreate could be very useful in. Link to post Share on other sites
JockoDundee 633 Posted July 3, 2021 Share Posted July 3, 2021 @BlackFlag, mark his post as the solution to increase its visibility… Code hard, but don’t hard code... Link to post Share on other sites
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