Page 5 of 6

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 08 Jun 2019, 07:49
by Helgef
or a function needs to be complex enough for MCode to be faster than regular AHK code?
Simply put, yes. The overhead of the dllcall outweighs any possible benefits for your example. Often, when you can replace a script loop with a compiled loop, then you can get speed benefits.

Any questions not related to joedf's app should probably go somewhere else.

Cheers.

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 08 Jun 2019, 08:17
by serg
@Helgef
Thanks for the answers!

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 08 Jun 2019, 08:43
by swagfag
dont call MCode on every loop iteration!! u do it once at the start
dont benchmark with too few iterations
dont benchmark with imprecise timers, use queryperformancecounter
dont benchmark without setbatchlines -1

for just multiplying 2 numbers * will probably be faster anyway

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 08 Jun 2019, 13:59
by joedf
@Helgef @swagfag Thanks! :+1:

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 20 Nov 2019, 13:46
by paulpma
Hello,

Is there a way to set MCODE encoding to hex vs base64(default) in the generator?. Have been searching but without any luck. Thank you.

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 20 Nov 2019, 22:05
by joedf
You have to change it under "Settings" here :thumbup: :
"Laszlo Style" for Hex
"Bentschi Style" for Base64

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 20 Nov 2019, 23:35
by paulpma
OMG.. thank you so much..

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 21 Nov 2019, 01:37
by joedf
No worries :+1:

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 23 Nov 2019, 23:16
by guest3456
bentschi's mcode:

Code: Select all

MCode(mcode)
{
  static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
  if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
    return
  if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
    return
  p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
  if (c="x64")
    DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
  if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
    return p
  DllCall("GlobalFree", "ptr", p)
}
are we sure VirtualProtect is only needed on AHKx64? and not 32?

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 24 Nov 2019, 02:19
by joedf
I dunno :think:

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 24 Nov 2019, 03:45
by Helgef
are we sure VirtualProtect is only needed on AHKx64? and not 32?
The function is known to work. However, I can't recall seeing any documentation suggesting the PAGE_EXECUTE_READWRITE flag is only for 64 bit, I've always set it for both 32 and 64 bit.

Cheers.

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 24 Nov 2019, 11:48
by guest3456
Helgef wrote:
24 Nov 2019, 03:45
are we sure VirtualProtect is only needed on AHKx64? and not 32?
The function is known to work. However, I can't recall seeing any documentation suggesting the PAGE_EXECUTE_READWRITE flag is only for 64 bit, I've always set it for both 32 and 64 bit.
i have a suspicion that VirtualProtect is necessary for 32bit as well, but i havent been able to confirm with my enduser yet

jeeswg wrote:
23 May 2018, 19:59
- [EDIT:] I noticed that the script is adding a trailing linefeed character when you click 'Copy to Clipboard'. And it adds them intermittently throughout long strings.
yeah and its only breaking up the Bentschi b64 mcode with linefeeds, its not breaking up the laszlo style hex

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 24 Nov 2019, 12:01
by joedf
Oops really? I must have missed this... :think:

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 24 Nov 2019, 12:17
by guest3456
looks like the CryptBinaryToString function appends newlines throughout the conversion after every 64th char. no idea why it does this

if we add the flag from msdn to the two calls, the newlines are removed:

Code: Select all

Base64enc( ByRef OutData, ByRef InData, InDataLen ) { ; by SKAN
	DllCall("Crypt32.dll\CryptBinaryToString" (A_IsUnicode?"W":"A")
		,UInt,&InData,UInt,InDataLen,UInt,0x40000001,UInt,0,UIntP,TChars,"CDECL Int")
	VarSetCapacity(OutData,Req:=TChars*(A_IsUnicode?2:1))
	DllCall("Crypt32.dll\CryptBinaryToString" (A_IsUnicode?"W":"A")
		,UInt,&InData,UInt,InDataLen,UInt,0x40000001,Str,OutData,UIntP,Req,"CDECL Int")
                msgbox %OutData%
	Return TChars
}
CRYPT_STRING_NOCRLF
0x40000000
Do not append any new line characters to the encoded string. The default behavior is to use a carriage return/line feed (CR/LF) pair (0x0D/0x0A) to represent a new line.
Windows Server 2003 and Windows XP: This value is not supported.

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 24 Nov 2019, 12:43
by jeeswg
AFAIK for hex it adds CRLFs and spaces, for base64 it adds CRLFs.
So you might want to do something like this:

Code: Select all

vText := RTrim(vText, " `r`n")
vText := StrReplace(vText, "`r`n")
vText := StrReplace(vText, " ")
;vText .= "`r`n" ;add this line, if a trailing CRLF is wanted
Since the raw hex/base64 flags are not supported on Windows XP.
Either drop the flag, and always do StrReplace.
Or check the OS version number, conditionally set the flag, and do StrReplace if necessary.
E.g. something like:

Code: Select all

JEE_HexGet(vAddr, vSize, vCase:="U")
{
	local
	static vIsVistaPlus := (DllCall("kernel32\GetVersion", "UInt") & 0xFF) >= 6
	vCase := "U"
	;CRYPT_STRING_NOCRLF := 0x40000000 (not supported by Windows XP)
	;CRYPT_STRING_HEXRAW := 0xC ;to return raw hex but with a trailing enter (not supported by Windows XP)
	;CRYPT_STRING_HEX := 0x4 ;to return space/CRLF-separated text
	vFlags := vIsVistaPlus ? 0x4000000C : 0x4
	vChars := 0
	DllCall("crypt32\CryptBinaryToString", "Ptr",vAddr, "UInt",vSize, "UInt",vFlags, "Ptr",0, "UInt*",vChars)
	VarSetCapacity(vHex, vChars*2, 0)
	DllCall("crypt32\CryptBinaryToString", "Ptr",vAddr, "UInt",vSize, "UInt",vFlags, "Str",vHex, "UInt*",vChars)
	if !vIsVistaPlus
	{
		vHex := StrReplace(vHex, "`r`n")
		vHex := StrReplace(vHex, " ")
	}
	return (vCase = "L") ? vHex : Format("{:U}", vHex)
}

JEE_Base64Get(vAddr, oParams*) ;vAddr, vSize
{
	local
	static vIsVistaPlus := (DllCall("kernel32\GetVersion", "UInt") & 0xFF) >= 6
	if (oParams.Length() = 2)
		vSize := oParams.1
	if !JEE_StrIsType(oParams.1, "number")
		vSize := 0
	else if (oParams.1 = 0)
		return
	else if oParams.HasKey(1)
		vSize := oParams.1
	else
		vSize := 0
	if !JEE_StrIsType(vSize, "number")
		vSize := 0
	;CRYPT_STRING_NOCRLF := 0x40000000
	;CRYPT_STRING_BASE64 := 0x1
	vChars := 0
	vFlags := vIsVistaPlus ? 0x40000001 : 0x1
	DllCall("crypt32\CryptBinaryToString", "Ptr",vAddr, "UInt",vSize, "UInt",vFlags, "Ptr",0, "UInt*",vChars)
	VarSetCapacity(vBase64, vChars*2, 0)
	DllCall("crypt32\CryptBinaryToString", "Ptr",vAddr, "UInt",vSize, "UInt",vFlags, "Str",vBase64, "UInt*",vChars)
	return vIsVistaPlus ? vBase64 : StrReplace(vBase64, "`r`n")
}
It would be good if a few of you supported me in getting base64/hex functionality built-in.
Either my code below, or something similar. Cheers.
C++: AHK source code: Base64Get/Base64Put and HexGet/HexPut - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=75&t=64694

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 24 Nov 2019, 12:52
by guest3456
jeeswg wrote:
24 Nov 2019, 12:43
AFAIK for hex it adds CRLFs and spaces, for base64 it adds CRLFs.
for Hex i'm not seeing any extra CRLF nor spaces

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 24 Nov 2019, 13:00
by jeeswg
StringToBinary is using fmt=12 by default:
CRYPT_STRING_HEXRAW := 0xC to return raw hex but with a trailing enter (not supported by Windows XP).
Anyhow, at least that explains the trailing enter.

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 24 Nov 2019, 15:46
by guest3456
jeeswg wrote:
24 Nov 2019, 13:00
StringToBinary is using fmt=12 by default:
CRYPT_STRING_HEXRAW := 0xC to return raw hex but with a trailing enter (not supported by Windows XP).
Anyhow, at least that explains the trailing enter.
StringToBinary isn't used for Hex output in this script, its only used for b64. The Hex is parsed directly from the compiler output.

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 24 Nov 2019, 18:20
by jeeswg
Thanks guest3456. OK, a summary:

Notes on how the hex/base64 is generated:
- Hex from: MCode_Generate (which uses the gcc exe) creates var x.
- Base64 from: Hex2Base64 (which uses StringToBinary, which uses the Winapi function CryptStringToBinary) applied to var x.

'Bentschi Style' option:
- Base64, 'Copy to Clipboard': there are CRLFs every 64 characters.
- Base64, copy directly from Edit4: there are CRLFs every 64 characters *and* a trailing CRLF.

'Laszlo Style' option (note: not 'Gangnam Style'):
- Hex, 'Copy to Clipboard': one long string with no spaces or CRs/LFs.
- Hex, copy directly from Edit4: the same.

I saw CRLFs only, fortunately no lone LFs (without CRs), which Notepad doesn't handle well.

The CopytoClipboard subroutine has this line:
Clipboard := Trim(StrReplace(x, "`n", "`r`n"), "`r`n")

So, recommendations would be:
- RTrim CRLFs before putting the base64 into the Edit control.
- Either split up the hex, or remove the splits (CRLFs) from the base64. I'm neutral re. this.

Btw can some recommend a C++ example, long enough to produce a long hex/base64 string? Thanks.
I used this (note: replace bool with _Bool before compiling with TDM-GCC):
case-insensitive searching in binary buffers - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=58103&p=255645#p255645

Re: MCode4GCC -- C/C++ to MCode Generator

Posted: 25 Nov 2019, 10:43
by joedf
Okay, I just committed a patch. Could anyone confirm it's fixed?
https://github.com/joedf/MCode4GCC/blob/master/MCode4GCC.ahk