#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 13 years ago by Jpm
comment:2 Changed 13 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 13 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.
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.