Jump to content

Shared Memory


mary
 Share

Recommended Posts

A shared memory is powerfull concept since all processors share a single view of data and the communication between processors can be as fast as memory accesses to a same location.

there are many c++ example ( http://www.codeproject.com/threads/sharedmemipc.asp ) but don't know if it is possible with autoit.

so my question is: is there API to create a shared memory ?

the idea is to create a shared global variable between many process (variable in RAM , NOT in disk)

thinks

Edited by mary
Link to comment
Share on other sites

A shared memory is powerfull concept since all processors share a single view of data and the communication between processors can be as fast as memory accesses to a same location.

there are many c++ example ( http://www.codeproject.com/threads/sharedmemipc.asp ) but don't know if it is possible with autoit.

so my question is: is there API to create a shared memory ?

the idea is to create a shared global variable between many process (variable in RAM , NOT in disk)

thinks

You just need to send a message from the program which decides what is stored where to the other program to tell it where the data is stored in memory. You will also need some sort of handshaking or special timing to ensure only one process reads or writes the data at a time, and something to indicate that the data is valid maybe. You could have one variable in the memory used to indicate valid data has been written by program A and that variable is only read by program B.

Suppose you create a struct with the types of data you want, then you can get the address of the struct with dllstructgetptr. Then send a message to the other program with this pointer value and the other program can then create the same struct but this time using the ptr so the struct will be at the same address. Then both programs will be dealing with the same memory.

CAVEAT. I haven't tried this, I'm just making it up as I go along. (Story of my life.)

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

You just need to send a message from the program which decides what is stored where to the other program to tell it where the data is stored in memory. You will also need some sort of handshaking or special timing to ensure only one process reads or writes the data at a time, and something to indicate that the data is valid maybe. You could have one variable in the memory used to indicate valid data has been written by program A and that variable is only read by program B.

Suppose you create a struct with the types of data you want, then you can get the address of the struct with dllstructgetptr. Then send a message to the other program with this pointer value and the other program can then create the same struct but this time using the ptr so the struct will be at the same address. Then both programs will be dealing with the same memory.

CAVEAT. I haven't tried this, I'm just making it up as I go along. (Story of my life.)

Clear as mud!

Link to comment
Share on other sites

.....

Suppose you create a struct with the types of data you want, then you can get the address of the struct with dllstructgetptr. Then send a message to the other program with this pointer value and the other program can then create the same struct but this time using the ptr so the struct will be at the same address. Then both programs will be dealing with the same memory.

CAVEAT. I haven't tried this, I'm just making it up as I go along. (Story of my life.)

DllStructGetPtr return a pointer ok, but it will not be accessible for other process (only for owner). maybe it can be shared if autoit can send adress memory like in c++ &DllStructGetPtr but autoit don't allow that :)

Edited by mary
Link to comment
Share on other sites

DllStructGetPtr return a pointer ok, but it will not be accessible for other process (only for owner). maybe it can be shared if autoit can send adress memory like in c++ &DllStructGetPtr but autoit don't allow that :)

Yes that's a problem. I don't understand the memory functions but maybe try posting a question in Wouter's mem example script thread asking how to allocate memory using the VM_SHARED permission.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Yes that's a problem. I don't understand the memory functions but maybe try posting a question in Wouter's mem example script thread asking how to allocate memory using the VM_SHARED permission.

I haven't worked out how to allocate a block of shared memory, but here is an example of one program reading the values in another program. Only integers but it shows the idea.

There are 2 scripts. Compile the talker one and run it, then run the listener. You can change the values of the numbers in the talker and the listener displays them.

Talker script

#include <GUIConstants.au3>
#include <misc.au3>
$Form2 = GUICreate("talker", 170, 160, 20, 200)
$Label1 = GUICtrlCreateLabel("a number to send", 20, 20, 87, 17)
$Input1 = GUICtrlCreateInput("78", 20, 45, 121, 21)
$Label2 = GUICtrlCreateLabel("another number to send", 20, 94, 150, 17)
$Input2 = GUICtrlCreateInput("587", 20, 110, 121, 21)
GUISetState(@SW_SHOW)


$Astruct = DllStructCreate("int[2]")
$Address = DllStructGetPtr($Astruct)
link()


While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
    
    If Not WinExists("listener") Then
        AdlibDisable()
        Exit;link()
    EndIf

    
WEnd

Func transmit()
;doesn't actually transmit anything, just writes the values in the sctruct so listener can read them
    DllStructSetData($Astruct, 1, Number(GUICtrlRead($Input1)), 1)
    DllStructSetData($Astruct, 1, Number(GUICtrlRead($Input2)), 2)
EndFunc;==>transmit


Func link()

    SplashTextOn("waiting for receiver to start", '', 200, 20, 20, 250)
    WinWait("listener", "")
    SplashOff()
        Sleep(200); if message sent too soon it's not received
    _SendMessage(WinGetHandle("listener"), 2000, $Address, $Address, 0, "ptr", "ptr")
    AdlibEnable("transmit", 200)
EndFunc;==>link

The listener script

#include <GUIConstants.au3>
#include <nomadmemory.au3>
#Region ### START Koda GUI section ### Form=
$Form2 = GUICreate("listener", 170, 160, 200, 200)
$Label1 = GUICtrlCreateLabel("some number", 20, 45, 87, 17)
$Label2 = GUICtrlCreateLabel("another number", 20, 110, 86, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
$pid = WinGetProcess("talker")
$MemOpen = _MemoryOpen ($pid)
$memadd = 0
AdlibEnable("update", 200)
GUIRegisterMsg(2000, "getaddr")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
    

    If Not WinExists("talker") Then Exit
    
WEnd
_memoryclose ($pid)

Func getaddr ($hWndGUI, $MsgID, $WParam, $LParam)
    If $MsgID = 2000 Then
;ConsoleWrite($WParam)
        $memadd = $WParam
    EndIf
EndFunc;==>getaddr

Func update ()
    If $memadd = 0 Then Return

    $disp = _MemoryRead ($memadd, $MemOpen, "int")
    GUICtrlSetData($Label1, $disp)

;I made hard work of next line, can't see how I should have done it
;$m2 = '0x' & String(Hex(Number($memadd) + 4, 8))
    $m2 = StringFormat("0x%x", number($memadd) + 4)
    $disp2 = _MemoryRead ($m2, $MemOpen, "int")
    GUICtrlSetData($Label2, $disp2)
    
EndFunc;==>update

EDIT: Added sleep(200) in talker because message didn't always get received

I got nomadmemory from here. I found it easier to use than wouter's mem udf; it's even got comments!

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

the goal of sharing memory between processes is to be more faster than registry or ini...your solution Inconvenience is to loop, sleep...

The example I showed uses Adlibenable which means the variables are only updated at the rate of the delay for ADlibenable. But it doesn't have to be done that way, I only intended to show how memory could be shared. If the variable to be read by the other program is simply written to the dllstruct whenever it is changed then the update is as fast as the receiving program can keep up with it. But have you got a better way I could learn from?

Or another thing I'd be interested to know is, how can you get the address of a variable in AutoIt apart from DllStructGetPtr? If you could get the address of a variable then it would all be much easier.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

The example I showed uses Adlibenable which means the variables are only updated at the rate of the delay for ADlibenable. But it doesn't have to be done that way, I only intended to show how memory could be shared. If the variable to be read by the other program is simply written to the dllstruct whenever it is changed then the update is as fast as the receiving program can keep up with it. But have you got a better way I could learn from?

Or another thing I'd be interested to know is, how can you get the address of a variable in AutoIt apart from DllStructGetPtr? If you could get the address of a variable then it would all be much easier.

address of a variable from DllStructGetPtr ok, but you can't send it to an other process (as $cmdLine or any other technique to share a variable between processes)

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...