Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Copy, Compare and Length of binary variables


  • Please log in to reply
3 replies to this topic
Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Variables containing binary data cannot be manipulated by standard AHK commands. Not even x = y type assignments work (x will be truncated at the first NULL of y). I tried DLL calls of RtlCompareMemory or RtlCopyBytes (referenced in MSDN), but in my XP system they are not part of the standard DLLs (a call gives ErrorLevel -4). I could only work with these data after converting them to a stream of hex digits and converting the result back at the end.

Also, their lengths have to be kept in separate variables. For example, VarSetCapacity allocates more memory than actually used. The following trick almost works:
VarSetCapacity(bin, len, 33)
StringLeft bin, bin, len
; write binary data to the memory of bin
Unfortunately, the length information, which is correct in the ListVars window is not accessible. StrLen(bin) shows the length only until the first NULL.

It would be nice to have this basic binary functionality. I don’t know if ClipBoardAll could contain a NULL, but if it could, assignment to a variable would truncate it.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
ClipboardAll produces flagged variables that get special handling, which is why it works there but not for other binary variables. I've made a note to look into making these binary-flagged variables available for more general use.

I was going to suggest RtlCompareMemory() because it seems to be in XP's kernel32.dll, but your results indicate it's not callable. So instead, you could use the C Runtime Library's memcmp(), located in msvcrt.dll (which almost all systems wind up having, though I'm not sure if it comes with 2k/XP). However, you would probably need to use DllCall's CDecl option to call it. There might also be name-not-found issues if the name is "mangled" inside the DLL.

Clearly, more improvements are needed to binary capabilities. One thing that is needed is the ability to reset the length of a variable to its proper value to avoid the problems you reported earlier. Another thing that would be convenient is being able to use a memory address on the left side of an assignment:

*Address := 15 ; Assign 15 directly to the byte at the indicated Address.

But these kind of features deserve careful thought before implementation to minimize regrets in the future.

If there's something for which you need a binary feature right away but can't get DllCall to work for, I can try to do it sooner. In addition, any other ideas you have for new built-in binary features (other than those you already posted) would be welcome. Thanks.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Typed variables look the cleanest solution. The corresponding data can be string, binary, unsigned or signed integers of different length, float, double, etc. Manipulating these variables is, of course, dependent on their types, but as we discussed it elsewhere it is not an afternoon job to do it right. Binary type looks the easiest to introduce, since the flagged ClipBoardAll data is already functional and there are not many commands that should be able to handle them: assignment, equality test, length. Accessing individual bytes can be done now with simple modifications of the ExtractInteger and InsertInteger functions (from the help on DllCall), or the pointer/reference method, which works already in expressions.

I stumbled on these problems, when I wrote my binary file I/O functions. I needed these for manipulating digital camera files (for random number generators used for crypto keys) and other binary files with random content, like sound files, microphone signals. The workaround of converting the binary buffers to hex strings solves most of the problems, but the running time suffers and the script gets so complex, that I might as well write a compiled C program.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004

assignment, equality test, length

I'll give these items a higher priority because of their usefulness. In the meantime, I think assignment could be done via RtlMoveMemory; equality test should be do-able via memcmp() from the C library (though for performance, you might want to do LoadLibrary on it to ensure it's memory resident); and as I think you mentioned, length could be tracked by the script itself in a separate variable (admittedly quite awkward).