26 (изменено: stealzy, 2017-11-15 04:53:32)

Re: AHK: Сравнение массива с массивом

А, понял, RtlCompareMemory может не быть в XP.

27

Re: AHK: Сравнение массива с массивом

Написано, что доступна, начиная с Windows 2000.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

28 (изменено: serzh82saratov, 2017-11-16 10:39:14)

Re: AHK: Сравнение массива с массивом

a := ["123", "123", "123", "222"]
b := ["123", "123", "123", "222"]

MsgBox % ArrayCompare(a, b)

ArrayCompare(obj1, obj2) {
	Loop 2
		VarSetCapacity(Bin%A_Index%, Size%A_Index% := RawObjectSize(obj%A_Index%, 0) + 8, 0)
		, RawObject(obj%A_Index%, NumPut(Size%A_Index% - 8, &Bin%A_Index%, "Int64"), 0)
	If (Size1 != Size2)
		Return 0
	Return !DllCall("msvcrt\memcmp", Ptr, &Bin1, Ptr, &Bin2, Ptr, Size1)
	  ;	Return Size1 = DllCall("NtDll\RtlCompareMemory", Ptr, &Bin1, Ptr, &Bin2, Ptr, Size1, Ptr)
}

RawObject(obj, addr, buf := 0, objects := 0) {
	; Type.Enum:    Char.1 UChar.2 Short.3 UShort.4 Int.5 UInt.6 Int64.7 UInt64.8 Double.9 String.10 Object.11
	; Negative for keys and positive for values
	If !objects
		objects:={(""):0,(obj):0}
	Else
		objects[obj]:=(++objects[""])
	for k, v in obj
	{ ; 9 = Int64 for size and Char for type
		If IsObject(k) {
			If objects.HasKey(k)
				NumPut(-12,addr+0,"Char"),NumPut(objects[k],addr+1,"Int64"),addr+=9
			Else
				NumPut(-11,addr+0,"Char"),NumPut(sz:=RawObjectSize(k,buf),addr+1,"Int64"),RawObject(k,addr+9,buf,objects),addr+=sz+9
		} Else
			NumPut(-10,addr+0,"Char"),NumPut(sz:=StrPut(k,addr+9)*2,addr+1,"Int64"),addr+=sz+9
		If IsObject(v) {
			If objects.HasKey(v)
				NumPut(12,addr+0,"Char"),NumPut(objects[v],addr+1,"Int64"),addr+=9
			Else
				NumPut(11,addr+0,"Char"),NumPut(sz:=RawObjectSize(v,buf),addr+1,"Int64"),RawObject(v,addr+9,buf,objects),addr+=sz+9
		} Else
			NumPut(10,addr+0,"Char"),NumPut(sz:=buf?obj.GetCapacity(k):StrPut(v)*2,addr+1,"Int64"),DllCall("RtlMoveMemory","PTR",addr+9,"PTR",buf?obj.GetAddress(k):&v,"PTR",sz),addr+=sz+9
	}
}

RawObjectSize(obj,buf:=0,objects:=0){
	If !objects
		objects:={(obj):1}
	Else If !objects.HasKey(obj)
		objects[obj]:=1
	for k, v in obj
	{
		If IsObject(k)
			sz+=objects.HasKey(k)?9:RawObjectSize(k,buf,objects)+9
		Else
			sz+=StrPut(k)*2+9
		If IsObject(v)
			sz+=objects.HasKey(v)?9:RawObjectSize(v,buf,objects)+9
		Else
			sz+=(buf?obj.GetCapacity(k):StrPut(v)*2)+9
	}
	Return sz
}
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).