Modify

Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#2161 closed Bug (No Bug)

DllStructs Corrupted When Returned In Array.

Reported by: anonymous Owned by:
Milestone: Component: AutoIt
Version: 3.3.8.0 Severity: None
Keywords: DllStruct Cc:

Description

When returning an array of DllStructs, they will sometimes be corrupted. I was using the following to rapidly pull data from a program. All of the data is perfect within the function itself, however the data will often be corrupted once returned (to be used elsewhere).

Func GetAgentArray($aType = 0)
	DllStructSetData($mMakeAgentArray, 2, $aType)
	MemoryWrite($mAgentCopyCount, -1, 'long')
	Enqueue($mMakeAgentArrayPtr, 8)
	Local $lDeadlock = TimerInit()
	Local $lCount = MemoryRead($mAgentCopyCount, 'long')
	While $lCount == -1 And TimerDiff($lDeadlock) < 5000
		Sleep(1)
		$lCount = MemoryRead($mAgentCopyCount, 'long')
	WEnd
;~ 	Above this line isn't directly related to bug
	Local $lBuffer = DllStructCreate('Byte[' & 448 * $lCount & ']')
	DllCall($mKernelHandle, 'int', 'ReadProcessMemory', 'int', $mGWProcHandle, 'int', $mAgentCopyBase, 'ptr', DllStructGetPtr($lBuffer), 'int', DllStructGetSize($lBuffer), 'int', '')
	Local $lReturnArray[$lCount + 1] = [$lCount]
	Local $lStructPtr = DllStructGetPtr($lBuffer)
	For $i = 1 To $lCount
		$lReturnArray[$i] = DllStructCreate('ptr vtable;byte unknown1[24];byte unknown2[4];ptr NextAgent;byte unknown3[8];long Id;float Z;byte unknown4[8];float BoxHoverWidth;float BoxHoverHeight;byte unknown5[8];float Rotation;byte unknown6[8];long NameProperties;byte unknown7[24];float X;float Y;byte unknown8[8];float NameTagX;float NameTagY;float NameTagZ;byte unknown9[12];long Type;float MoveX;float MoveY;byte unknown10[28];long Owner;byte unknown30[8];long ExtraType;byte unknown11[24];float AttackSpeed;float AttackSpeedModifier;word PlayerNumber;byte unknown12[6];ptr Equip;byte unknown13[10];byte Primary;byte Secondary;byte Level;byte Team;byte unknown14[6];float EnergyPips;byte unknown[4];float EnergyPercent;long MaxEnergy;byte unknown15[4];float HPPips;byte unknown16[4];float HP;long MaxHP;long Effects;byte unknown17[4];byte Hex;byte unknown18[18];long ModelState;long TypeMap;byte unknown19[16];long InSpiritRange;byte unknown20[16];long LoginNumber;float ModelMode;byte unknown21[4];long ModelAnimation;byte unknown22[32];byte LastStrike;byte Allegiance;word WeaponType;word Skill;byte unknown23[4];word WeaponItemId;word OffhandItemId', $lStructPtr)
		$lStructPtr += 448
;~ 		Data is perfect when written to console here.
	Next
	Return $lReturnArray
EndFunc   ;==>GetAgentArray

But when called with the following, it will give me lots of bad information. If I don't set $arr to 0 (like I do in the following), it will (usually) stop causing issues after a few calls. (Probably a memory allocation issue.)

While 1
	Local $arr = Getagentarray(0x400)
	If $arr[0] = 0 Then ContinueLoop
	out(DllStructGetData($arr[1], 'X')) ;Data is very often incorrect.
	$arr = 0
	Sleep(20)
WEnd

Attachments (0)

Change History (3)

comment:1 Changed 7 years ago by Jpm

Can you post a complete script as for instance the $mMakeAgentArray is not defined when entering the Func?
It is always better toa sk to the forum first before submitting track report.

comment:2 Changed 7 years ago by trancexx

  • Resolution set to No Bug
  • Status changed from new to closed

$lBuffer is structure on local scope. After function returns that struct is destroyed, occupied memory space freed.
Structure that you export is created at place of mentioned local struct - remember that no allocation is done if you pass memory pointer as second parameter for DllStructCreate() function.

It's expected that your data is corrupted.
You probably want to copy data from one struct to another. It's not that hard to achieve that, just think more. If you would fail use the forum for help.

Also, even though it's not a requirement it would be nice if you weren't anonymous. Being anonymous is lame. How do I know you aren't some serial killer? I probably shouldn't talk to you :P

comment:3 Changed 7 years ago by anonymous

Alrighty, makes sense. I was operating under the assumption that autoit would preserve the structure (or the parts of the structure) as long as there was an active "pointer" being used. (This may or may not be worth adding to the documentation)

Since it was so sporadic when called in a loop, I just assumed it was data corruption. It's obvious now that I know, I just didn't make the connection. Thanks for the help.

And for anyone it might help, this solves the issue.

	Local $lStruct
	Local $lCount
	Local $lBuffer = ''
	DllStructSetData($mMakeAgentArray, 2, $aType)
	MemoryWrite($mAgentCopyCount, -1, 'long')
	Enqueue($mMakeAgentArrayPtr, 8)
	Local $lDeadlock = TimerInit()
	Do
		Sleep(1)
		$lCount = MemoryRead($mAgentCopyCount, 'long')
	Until $lCount >= 0 Or TimerDiff($lDeadlock) > 5000
	For $i = 1 To $lCount
		$lBuffer &= 'Byte[448];'
	Next
	$lBuffer = DllStructCreate($lBuffer)
	DllCall($mKernelHandle, 'int', 'ReadProcessMemory', 'int', $mGWProcHandle, 'int', $mAgentCopyBase, 'ptr', DllStructGetPtr($lBuffer), 'int', DllStructGetSize($lBuffer), 'int', '')
	Local $lReturnArray[$lCount + 1] = [$lCount]
	For $i = 1 To $lCount
		$lReturnArray[$i] = DllStructCreate('ptr vtable;byte unknown1[24];byte unknown2[4];ptr NextAgent;byte unknown3[8];long Id;float Z;byte unknown4[8];float BoxHoverWidth;float BoxHoverHeight;byte unknown5[8];float Rotation;byte unknown6[8];long NameProperties;byte unknown7[24];float X;float Y;byte unknown8[8];float NameTagX;float NameTagY;float NameTagZ;byte unknown9[12];long Type;float MoveX;float MoveY;byte unknown10[28];long Owner;byte unknown30[8];long ExtraType;byte unknown11[24];float AttackSpeed;float AttackSpeedModifier;word PlayerNumber;byte unknown12[6];ptr Equip;byte unknown13[10];byte Primary;byte Secondary;byte Level;byte Team;byte unknown14[6];float EnergyPips;byte unknown[4];float EnergyPercent;long MaxEnergy;byte unknown15[4];float HPPips;byte unknown16[4];float HP;long MaxHP;long Effects;byte unknown17[4];byte Hex;byte unknown18[18];long ModelState;long TypeMap;byte unknown19[16];long InSpiritRange;byte unknown20[16];long LoginNumber;float ModelMode;byte unknown21[4];long ModelAnimation;byte unknown22[32];byte LastStrike;byte Allegiance;word WeaponType;word Skill;byte unknown23[4];word WeaponItemId;word OffhandItemId')
		$lStruct = DllStructCreate('byte[448]', DllStructGetPtr($lReturnArray[$i]))
		DllStructSetData($lStruct, 1, DllStructGetData($lBuffer, $i))
	Next
	Return $lReturnArray

Guidelines for posting comments:

  • You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
  • In-depth discussions should take place on the forum.

For more information see the full version of the ticket guidelines here.

Add Comment

Modify Ticket

Action
as closed The ticket will remain with no owner.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.