The consensus in that thread was that VarSetCapacity() is just fine the way it is, but that someone might find it convenient to have variable initialization and getting the variable's address all in one function.
So, I came up with this. At it's simplest level, this function is the same as Laszlo's mighty MCode() function. Here's a summary of the bells and whistles I added:[*:21fktfo6] Returns the address of 'var'
[*:21fktfo6] The hex string may (or may not) start with "0x" and may be an odd number of characters long (an implicit '0' is appended to odd-length strings)
[*:21fktfo6] The byte sequence represented by the hex string may be replicated any number of times.
[*:21fktfo6] Compatible with AHK-L and AHK-Basic
VarInit( BYREF var, hex_string, multiplier = 1 ) { ; > http://www.autohotkey.com/forum/viewtopic.php?t=83760
; Function by [VxE]. Allocates space for a variable, insert data from a hex string (optionally replicating the
; byte sequence multiple times) and return the variable's address.
oel := ErrorLevel, Ptr := !A_PtrSize ? "UInt" : "Ptr", multiplier := 1 < multiplier ? 0 | multiplier : 1
StringTrimLeft hex_string, hex_string, 1 = InStr( hex_string, "0x" ) ? 2 : 0
If ( 1 < byte_count := 1 + StrLen( hex_string ) >> 1 )
{
VarSetCapacity( var, byte_count * multiplier + 2 ), hex_string .= "0"
Loop % byte_count
NumPut( "0x" SubStr( hex_string, 2 * A_Index - 1, 2 ), var, A_Index - 1, "Char" )
Loop % Ceil( Ln( multiplier ) / Ln( 2 ) )
DllCall( "RtlMoveMemory", Ptr, &var + ( byte_count << A_Index - 1 ), Ptr, &var, "UInt", multiplier >> A_Index ? byte_count << A_Index - 1 : byte_count * ( multiplier - ( 1 << A_Index - 1 ) ) )
}
Else VarSetCapacity( var, byte_count * multiplier + 2, hex_string = "" ? 0 : "0x" string )
Return &var, NumPut( 0, var, byte_count * multiplier, "Short" ), ErrorLevel := oel
}
Example:
; Create a string of "123" repeated 1000 times VarInit( string, A_IsUnicode ? "310032003300" : "313233", 1000 ) VarSetCapacity( string, -1 ) MsgBox %string%




