E1M1

how to get pointer/address of array?

13 posts in this topic

#1 ·  Posted (edited)

how do i get pointer of array? if it's possible. In C it should be &array but how it is in autoit? I also looked at DllStructCreate() but I didn't find anything to create array like struct.

I need to get pointer of $array bacause I wan't to copy it to other's process memory.

Edited by E1M1

edited

Share this post


Link to post
Share on other sites



I know very little about this, but I have read that you cannot just get a pointer to an array in au3, the data is not always stored in that fasion.

You mentioned DllStructCreate(), and from what I've seen thats exactly what you need (for what you are tyying), I'm not saying its possible unless the process is a child of the main.

Then you want to be looking at DllStructGetPtr()


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

Maybe this will make things more clear for you:

$stStruct=DLLStructCreate("byte[4]")
DllStructSetData($stStruct,1,"0x909090C3")
$pPtr=DllStructGetPtr($stStruct)
ConsoleWrite("Struct at "&$pPtr&", 1st byte of 1st element: 0x"&Hex(DllStructGetData($stStruct,1,1),2)&@CRLF)
ConsoleWrite("Complete 1st element:"&DllStructGetData($stStruct,1)&@CRLF)

Share this post


Link to post
Share on other sites

Use an byte array, so you can store every type of data in your array.

; example: integer-array with 5 elements

; === 1. get size of one element
$SIZE = DllStructGetSize(DllStructCreate('int', 1))
; the '1' is not really a pointer adress, it will used as base to calculate

; === 2. create byte array with count of elements
$aBYTE = DllStructCreate('byte[' & $SIZE *5 & "]")

; === 3. get pointer of your byte array
$pByteArray = DllStructGetPtr($aBYTE)

; === 4. create structure for every element
$Element_0 = DllStructCreate('int', DllStructGetPtr($aBYTE))
$Element_1 = DllStructCreate('int', DllStructGetPtr($aBYTE + $SIZE))
$Element_2 = DllStructCreate('int', DllStructGetPtr($aBYTE + $SIZE*2))
$Element_3 = DllStructCreate('int', DllStructGetPtr($aBYTE + $SIZE*3))
$Element_4 = DllStructCreate('int', DllStructGetPtr($aBYTE + $SIZE*4))

; === alternatively store structures in an own array:
Local $aStructData[4]
For $i = 0 To 4
    $aStructData[$i] = DllStructCreate('int', DllStructGetPtr($aBYTE + $SIZE*$i))
Next

; === 5. set values
$value = 123
DllStructSetData($aStructData[0], 1, $value)

; === 6. get values
$value = DllStructGetData($aStructData[0], 1)

Best Regards BugFix  

Share this post


Link to post
Share on other sites

Bugfix, that's really too much. If you want an array of 5 int's, use 'int[5]' in your structure definition.

If you really need to access the data as another datatype, its simple enough to 'cast' it by using another DLLStructCreate(), but with a pointer to that initial array.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Bugfix, that's really too much. If you want an array of 5 int's, use 'int[5]' in your structure definition.

If you really need to access the data as another datatype, its simple enough to 'cast' it by using another DLLStructCreate(), but with a pointer to that initial array.

Do you mean?

Local $array[3]
$array[0] = "text"
$array[1] = "text2"
$array[2] = "10"

;~ MsgBox(0,0,Binary($array))
$struct = DllStructCreate("char[255]",$array)

@Ascend4nt I tried to modify your struc, buti can't set "test as first element"

$stStruct=DLLStructCreate("char[8]")
DllStructSetData($stStruct,1,"abcdefgh")
DllStructSetData($stStruct,1,"test",1)
$pPtr=DllStructGetPtr($stStruct)
ConsoleWrite("Struct at "&$pPtr&", 1st byte of 1st element: "&DllStructGetData($stStruct,1,1)&@CRLF)
ConsoleWrite("Complete 1st element:"&DllStructGetData($stStruct,1)&@CRLF)

I wan't to put this in struct.

Local $array[3]
$array[0] = "text"
$array[1] = "text2"
$array[2] = "10"

I want it all be in 1 struct on 1 element.

Edited by E1M1

edited

Share this post


Link to post
Share on other sites

You know, I really shouldn't have to point out the obvious; it seems you just don't want to give ANY effort into understanding underlying structures, individual elements, pointers, etc etc. I give up. Like trancexx once suggested - go read something, anything.

..read other people's code, read tutorials. Read your own darn code!

And don't just run back here when something doesn't work. Find out WHY. Analyze that code. Use debugging statements and tools. (my _DLLStructDisplay tool actually may help you understand something in this scenario).

Just play around with your code and the results - and try to understand it. And don't bother PM'ing me asking for me to convert an entire piece of code for you.

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

How you can say I have't made any effort to understand it after I have tried code here and tried to modify it? How would you like if I would say you made no effort to teach me?

I originally asked about how to put array into 1 binary string. With array I meant something like foolowing:

Local $array[3]

$array[0] = "text"

$array[1] = "text2"

$array[2] = "10"

What you gave me is off topic. your's array is just like string. Your structure is just separated strings, not array. It cannot have string as one array element. I know structs like char,int,ptr and so on but you wrote this message as i would know nothing. If autoit can't have whole $array in 1 struct it doesn't mean I made no effort.

I can analyse my code but I cannot anayle array that does not exist. And I repeat - what you gave me is not nearly array[n].

When you say that I PMed you to convert entire piece of code for me I can say that you completely misundertood idea of my PM. I already had that code converted and I only asked if and what I did wrong there. But don't worry I won't PM anymore. It was just mistake from me. forgive me that.

Thanks alot for help.

Edited by E1M1

edited

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

On 07/09/2010 at 10:16 PM, BugFix said:

Use an byte array, so you can store every type of data in your array.

 

 

; example: integer-array with 5 elements

; === 1. get size of one element
$SIZE = DllStructGetSize(DllStructCreate('int', 1))
; the '1' is not really a pointer adress, it will used as base to calculate

; === 2. create byte array with count of elements
$aBYTE = DllStructCreate('byte[' & $SIZE *5 & "]")

; === 3. get pointer of your byte array
$pByteArray = DllStructGetPtr($aBYTE)

; === 4. create structure for every element
$Element_0 = DllStructCreate('int', DllStructGetPtr($aBYTE))
$Element_1 = DllStructCreate('int', DllStructGetPtr($aBYTE + $SIZE))
$Element_2 = DllStructCreate('int', DllStructGetPtr($aBYTE + $SIZE*2))
$Element_3 = DllStructCreate('int', DllStructGetPtr($aBYTE + $SIZE*3))
$Element_4 = DllStructCreate('int', DllStructGetPtr($aBYTE + $SIZE*4))

; === alternatively store structures in an own array:
Local $aStructData[4]
For $i = 0 To 4
    $aStructData[$i] = DllStructCreate('int', DllStructGetPtr($aBYTE + $SIZE*$i))
Next

; === 5. set values
$value = 123
DllStructSetData($aStructData[0], 1, $value)

; === 6. get values
$value = DllStructGetData($aStructData[0], 1)

 

Hey Forum World! I know this is an old post but I hoping someone can help me out with something. The quoted explanation looked fantastic to me and so I read and learnt from it, except for one problem, which is that it is wrong and when you run the code it doesn't work. The relative addressing, using the byte array pointer as the starting point and adding to the address according to the size of the individual record multiplied by 2, 3, 4, this doesn't actually work.

Please can someone explain how to do this correctly. I have done some c programming and I think this is just a guy making the mistake of  applying good c coding in the autoit language, which doesn't work. the problem is I don't really understand how you are supposed to work with c variables in autoit, it seems autoit is pretty high level and despite having read up alot on it I can't seem to grasp how to create an array containing structs which can be passed as a pointer to a windows DLL function.

in c I could just write:

 

#define NumberOfRecords 2
struct RecordDefinition
{
    HANDLE hPhysicalMonitor
    WCHAR  szPhysicalMonitorDescription[128]
};

struct RecordDefinition ArrayOfRecords[NumberOfRecords];

 

Help! :) 

 

please

 

p.s. the DLL function I am using that requires a pointer to an array of structs is the following:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd692950(v=vs.85).aspx

Edited by Lexeus

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Well 2 days wasted and now I realise what was wrong:

everywhere in the example where the DLLStructGetPtr commands are used, the brackets are in the wrong place.

e.g.

example states: 

    $aStructData[$i] = DllStructCreate('int', DllStructGetPtr($aBYTE + $SIZE*$i))

the correct example would be:

    $aStructData[$i] = DllStructCreate('int', DllStructGetPtr($aBYTE) + $SIZE*$i)
Edited by Lexeus

Share this post


Link to post
Share on other sites

If anyone has any suggestions on how to use this dll in a more elegant way I would be very glad to hear them please!  https://msdn.microsoft.com/en-us/library/windows/desktop/dd692950(v=vs.85).aspx

For now I am going to use this route of allocating a #c struct byte array with the correct number of bytes and then repurposing the memory for each and every record that i need by creating them individually as a #c struct within the original byte array memory and then allocating each one into an autoit array element. That way I can just pass the dll function a pointer to the original #c struct byte array i hope....

Share this post


Link to post
Share on other sites

Hello You can do something Like this...

#include <WinAPIGdi.au3>
#include <Array.au3> ;just for Debug


Global Const $PHYSICAL_MONITOR_DESCRIPTION_SIZE = 128

;~   PHYSICAL_MONITOR structure
;~   HANDLE hPhysicalMonitor;
;~   WCHAR  szPhysicalMonitorDescription[PHYSICAL_MONITOR_DESCRIPTION_SIZE];
Global Const $sTagPHYSICAL_MONITOR = "handle;wchar[128];"

Local $aMonitors = _WinAPI_EnumDisplayMonitors()
;~ _ArrayDisplay($aMonitors)
Local $hMonitor = $aMonitors[1][0]



Local $aRet = DllCall("Dxva2.dll", "bool", "GetNumberOfPhysicalMonitorsFromHMONITOR", "handle", $hMonitor, "dword*", 0)
Local $iNumberOfPhysicalMonitors = $aRet[2]
ConsoleWrite("Number Of Physical Monitors: " & $iNumberOfPhysicalMonitors & @CRLF)


Local $sStringTagStructure = ""
For $i = 1 To $iNumberOfPhysicalMonitors
    $sStringTagStructure &= $sTagPHYSICAL_MONITOR
Next

Local $tArrayPHYSICAL_MONITOR = DllStructCreate($sStringTagStructure)

Local $PtrPhysicalMonitorArray = DllStructGetPtr($tArrayPHYSICAL_MONITOR)

$aRet = DllCall("Dxva2.dll", "bool", "GetPhysicalMonitorsFromHMONITOR", "handle", $hMonitor, "dword", $iNumberOfPhysicalMonitors, "ptr", $PtrPhysicalMonitorArray)


For $i = 1 To $iNumberOfPhysicalMonitors
    ConsoleWrite("hPhysicalMonitor: " & DllStructGetData($tArrayPHYSICAL_MONITOR, (($i) * 2) - 1) & @CRLF)
    ConsoleWrite("PhysicalMonitorDescription: " & DllStructGetData($tArrayPHYSICAL_MONITOR, (($i) * 2)) & @CRLF)
Next


$tArrayPHYSICAL_MONITOR=0;free

Saludos

2 people like this

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

Well, a few days ago, when i requested to implement pointers in AutoIt, all experts were told me that to go and find another language that suits your needs. AutoIt is not meant to be working with pointers or direct memory manipulation. Its for easy automation. 

Edited by kcvinu

My Contributions

UDF Link Viewer   --- A tool to visit the links of some most important UDFs 

 Includer_2  ----- A tool to type the #include statement automatically 

 Digits To Date  ----- date from 3 integer values

PrintList ----- prints arrays into console for testing.

 Alert  ------ An alternative for MsgBox 

 MousePosition ------- A simple tooltip display of mouse position

GRM Helper -------- A littile tool to help writing code with GUIRegisterMsg function

Access_UDF  -------- An UDF for working with access database files. (.*accdb only)

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now