livewire Posted August 30, 2007 Share Posted August 30, 2007 Here is an example of sharing memory between two AutoIt scripts using a dll. If anyone has any info on how to make the dll better, let me know. Run both scripts at the same time with the dll in the same path to use. Dll Code: expandcollapse popup#include <windows.h> #include <memory.h> #include <string.h> #define SHMEMSIZE 4096 static LPVOID lpvMem = NULL; // pointer to shared memory static HANDLE hMapObject = NULL; // handle to file mapping // The DLL entry-point function sets up shared memory using a // named file-mapping object. BOOL WINAPI DllMain(HINSTANCE hinstDLL, // DLL module handle DWORD fdwReason, // reason called LPVOID lpvReserved) // reserved { BOOL fInit, fIgnore; switch (fdwReason) { // DLL load due to process initialization or LoadLibrary case DLL_PROCESS_ATTACH: // Create a named file mapping object hMapObject = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file NULL, // default security attributes PAGE_READWRITE, // read/write access 0, // size: high 32-bits SHMEMSIZE, // size: low 32-bits TEXT("dllmemfilemap")); // name of map object if (hMapObject == NULL) return FALSE; // The first process to attach initializes memory fInit = (GetLastError() != ERROR_ALREADY_EXISTS); // Get a pointer to the file-mapped shared memory lpvMem = MapViewOfFile( hMapObject, // object to map view of FILE_MAP_WRITE, // read/write access 0, // high offset: map from 0, // low offset: beginning 0); // default: map entire file if(lpvMem == NULL) return FALSE; // Initialize memory if this is the first process if(fInit) memset(lpvMem, '', SHMEMSIZE); break; // The attached process creates a new thread case DLL_THREAD_ATTACH: break; // The thread of the attached process terminates case DLL_THREAD_DETACH: break; // DLL unload due to process termination or FreeLibrary case DLL_PROCESS_DETACH: // Unmap shared memory from the process's address space fIgnore = UnmapViewOfFile(lpvMem); // Close the process's handle to the file-mapping object fIgnore = CloseHandle(hMapObject); break; default: break; } return TRUE; UNREFERENCED_PARAMETER(hinstDLL); UNREFERENCED_PARAMETER(lpvReserved); } // SetSharedMem sets the contents of the shared memory VOID _stdcall SetSharedMem(char *str) { char *lpszTmp; // Get the address of the shared memory block lpszTmp = (char *) lpvMem; strncpy(lpszTmp,str,SHMEMSIZE); } // GetSharedMem gets the contents of the shared memory VOID _stdcall GetSharedMem(char *str, int size) { char *lpszTmp; // Get the address of the shared memory block lpszTmp = (char *) lpvMem; strncpy(str,lpszTmp,size); } 1st Script: expandcollapse popup#include <GUIConstants.au3> Dim $dll Dim $ret Dim $read_string = "" $dll = DllOpen("SharedMemory.dll") If @error Then MsgBox(0,"Testing","Error opening dll") EndIf $Form1 = GUICreate("Test1", 360, 321, 280, 230) $Button1 = GUICtrlCreateButton("SetSharedMem", 40, 40, 81, 25, 0) $Button2 = GUICtrlCreateButton("GetSharedMem", 43, 70, 81, 25, 0) $Input1 = GUICtrlCreateInput("", 144, 40, 153, 21) $Input2 = GUICtrlCreateInput("", 144, 72, 153, 21) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $Button1 DllCall($dll,"none","SetSharedMem","str",GUICtrlRead($Input1)) If @error Then MsgBox(0,"Testing","Error calling SetSharedMem") Exit EndIf Case $Button2 $ret = DllCall($dll,"none","GetSharedMem","str",$read_string,"int",50) If @error Then MsgBox(0,"Testing","Error calling GetSharedMem") Exit Else GUICtrlSetData($Input2,$ret[1]) EndIf Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd DllClose($dll) If @error Then MsgBox(0,"Testing","Error closing dll") EndIfSharedMemory.zip Link to comment Share on other sites More sharing options...
zatorg Posted August 30, 2007 Share Posted August 30, 2007 Nice. Simple and pretty CreateFileMapping( INVALID_HANDLE_VALUE, // ... Question: why do you want to explicitly use swap? I mean, using physical memory would be faster... And now, everytime the memory is accessed, a paging fault occurs and the system moves the data from pagefile.sys (or whatever) to physical RAM... :/ Anyway, I like the simplicity Link to comment Share on other sites More sharing options...
martin Posted August 30, 2007 Share Posted August 30, 2007 Here is an example of sharing memory between two AutoIt scripts using a dll. If anyone has any info on how to make the dll better, let me know. Run both scripts at the same time with the dll in the same path to use.That works well and it is a different approach to anything I have tried so far.I have only just started trying to use memory and I understand very little so I can't make any useful comments about your dll, but I have some questions.1. Do you think you could have done the same with the available memory udf's, and if not why not?2. Can you tell me the advantages of the way you have done it compared to the example I gave in the 'Data Interchange between scripts' thread. (here)3. I find it a bit slow going understanding the memory functions. Can you give any links for an idiot's guide to memory usage? I don't understand memory maps (or rather I know what a memory map is but not the way memory is organised, allocated, used etc), access rights, you name it. 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 More sharing options...
livewire Posted August 30, 2007 Author Share Posted August 30, 2007 That works well and it is a different approach to anything I have tried so far.I have only just started trying to use memory and I understand very little so I can't make any useful comments about your dll, but I have some questions.1. Do you think you could have done the same with the available memory udf's, and if not why not?2. Can you tell me the advantages of the way you have done it compared to the example I gave in the 'Data Interchange between scripts' thread. (here)3. I find it a bit slow going understanding the memory functions. Can you give any links for an idiot's guide to memory usage? I don't understand memory maps (or rather I know what a memory map is but not the way memory is organised, allocated, used etc), access rights, you name it.I found this code on codeproject and changed it to work with AutoIt.1. I haven't used the memory udfs. But in the quick glance that I looked at it, I'm sure you could do the same.Sorry, I can't answer those complicated memory questions. I was hoping someone could just change the code if it's possible to: not use swap, not use dll, etc. Link to comment Share on other sites More sharing options...
Michel Claveau Posted August 31, 2007 Share Posted August 31, 2007 (edited) Hi, Livewire! You are FANTASTIC!!! Your Script/Method/DLL is compatible with the mmap module/methods of Python (programming language). And, like the memmap library, in Ruby, is compatible with Python, I think that your work is also compatible with Ruby. If you want... just an enhancement : the possibity to choose/drive the name of the mapping (change "dllmemfilemap" to parameter) EDIT: and also, put the size of buffer (actually 4096) like parameter (and ***sorry for my bad english***) Edited August 31, 2007 by Michel Claveau Link to comment Share on other sites More sharing options...
Michel Claveau Posted September 1, 2007 Share Posted September 1, 2007 (edited) Re, Livewire; Please... Which C compiler had you use, for create the DLL? I had try with TCC, but the DLL don't run (and I don't know C) Edited September 1, 2007 by Michel Claveau Link to comment Share on other sites More sharing options...
zatorg Posted September 1, 2007 Share Posted September 1, 2007 Try GNU's g++, it's open source (default in Code::Blocks and Dev-Cpp IDE). An alternative would be Microsoft Visual C++ or Microsoft Visual Studio. I suppose Visual Studio is the best choice when programming Windows applications. Link to comment Share on other sites More sharing options...
Michel Claveau Posted September 1, 2007 Share Posted September 1, 2007 (edited) Hi! Thank you, Zatorg ! I have MinGW (because I test Pyrex). I had can compile a DLL. But I don't know C, then I don't know how to make a function for put "name" & "size" like parameters. But, I change the buffer size to 32767, and the name to "autoitmmap" (this name is not used in the Livewire's exemple) Also, I had renamed the DLL to autoitmmap.dll (for no confuse with livewire's work) For compile, I found that : create the file autoitmmap.def (who contain the exports names of functions) gcc -c -I"D:\dev\MinGW\include" -enable-stdcall-fixup -o autoitmmap.o autoitmmap.c gcc -shared -I"D:\dev\MinGW\include" -enable-stdcall-fixup -o autoitmmap.dll autoitmmap.c autoitmmap.def The result is a file, with a little size. This file run with Livewire's exemple (only change the name of DLL) And, a source code, in Python, for exchange data with AutoIt : import mmap data='Qwerty1234567890' # write data objmmap=mmap.mmap(0,32767,'autoitmmap') objmmap.seek(0) objmmap.write(data) objmmap.flush() raw_input('write Ok; [Enter] for read') #read data objmmap.seek(0) receiv=objmmap.read(32767) print len(receiv),receiv #objmmap.close() #option I give the DLL in attachment.autoitmmap.dll Edited September 1, 2007 by Michel Claveau Link to comment Share on other sites More sharing options...
martin Posted September 1, 2007 Share Posted September 1, 2007 Nice. Simple and pretty CreateFileMapping( INVALID_HANDLE_VALUE, // ... Question: why do you want to explicitly use swap? I mean, using physical memory would be faster... And now, everytime the memory is accessed, a paging fault occurs and the system moves the data from pagefile.sys (or whatever) to physical RAM... :/ Anyway, I like the simplicity What is needed to use physical memory? I assume I would need AWE but I don't know how to set that up in XP home so if you can advise I would be very pleased. Can you answer any of my questions in post #3? 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 More sharing options...
livewire Posted September 1, 2007 Author Share Posted September 1, 2007 Hi, Livewire!You are FANTASTIC!!!Your Script/Method/DLL is compatible with the mmap module/methods of Python (programming language).And, like the memmap library, in Ruby, is compatible with Python, I think that your work is also compatible with Ruby.If you want... just an enhancement : the possibity to choose/drive the name of the mapping (change "dllmemfilemap" to parameter)EDIT: and also, put the size of buffer (actually 4096) like parameter(and ***sorry for my bad english***)Sounds good...will try to do that.Re, Livewire;Please... Which C compiler had you use, for create the DLL? I had try with TCC, but the DLL don't run (and I don't know C)Microsoft Visual C++ 6.0, but should be able to get it to compile using 2005 or devC++.-Livewire Link to comment Share on other sites More sharing options...
Michel Claveau Posted September 1, 2007 Share Posted September 1, 2007 (edited) Hi! Livewire, your C-source-code, give a 200 kB DLL with MS-VC++, but give a 15 kB with MinGW... Finding: for your next release, keep yet to give the source. Thanks by advance. Edited September 1, 2007 by Michel Claveau Link to comment Share on other sites More sharing options...
mary Posted September 1, 2007 Share Posted September 1, 2007 is it faster than RamDisk technique to share variables between processes ? Link to comment Share on other sites More sharing options...
martin Posted September 1, 2007 Share Posted September 1, 2007 is it faster than RamDisk technique to share variables between processes ?How do you make a RAMDISK?The best way to see if it's faster or not is to try some tests. 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 More sharing options...
Michel Claveau Posted September 2, 2007 Share Posted September 2, 2007 Hi, Mary!is it faster than RamDisk technique to share variables between processes ?Yes, it's faster. But it's less powerful and less easy. Because a RAMDisk manage all the files-system, contrary to the technique used here. Link to comment Share on other sites More sharing options...
zatorg Posted September 2, 2007 Share Posted September 2, 2007 (Have been away for some time..)What is needed to use physical memory?Physical memory is the memory in RAM disks. When an OS runs out of physical RAM, it uses virtual memory (setting up VM). Windows allocates a paging file (PF, typically pagefile.sys) on the hard disk to use it instead of physical RAM when running low on free physical memory.So when one isn't using physical memory ("real" RAM) then he/she is using virtual memory which is on a hard disk thus much slower to read/write to.(Actually, to be accurate virtual memory is physical memory plus "swap" (paging/swap files))Anyway, sorry for the ignorance, too lazy and haven't got much time. Link to comment Share on other sites More sharing options...
martin Posted September 2, 2007 Share Posted September 2, 2007 (Have been away for some time..)Physical memory is the memory in RAM disks. When an OS runs out of physical RAM, it uses virtual memory (setting up VM). Windows allocates a paging file (PF, typically pagefile.sys) on the hard disk to use it instead of physical RAM when running low on free physical memory.So when one isn't using physical memory ("real" RAM) then he/she is using virtual memory which is on a hard disk thus much slower to read/write to.(Actually, to be accurate virtual memory is physical memory plus "swap" (paging/swap files))Anyway, sorry for the ignorance, too lazy and haven't got much time.Just a follow up on the memory used by the dll. It looks to me like the dll uses physical memory which is the default for the CreateFileMapping API, and the INVALID_HANDLE_VALUE isn't related to that, but to whether the memory map is defined in a file or not. Info from here.It also looks to me like the dll could be replaced by AutoIt code since it appears to be based on calls to kernel32.dll.One of the things I don't know is what are the benefits, if any, of using allocating memory like this compared to memory used by a DllStructCreate, and then read by another process. Can anyone can enlighten me? 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 More sharing options...
zatorg Posted September 3, 2007 Share Posted September 3, 2007 (edited) HANDLE WINAPI CreateFileMapping( HANDLE [i]hFile[/i], Darn! CreateFileMapping() always allocates memory on a physical hard disk, not in physical memory This means that DllStructCreate() / memory allocation at runtime should (only thought, no experience) be faster than CreateFileMapping(). Although CreateFileMapping() is intended for shared memory access etc. and DllStructCreate() is not, DllStructCreate() may allocate memory pages in physical memory whereas CreateFileMapping (darn I'm stupid) allocates memory on a paging file. hFile [in] A handle to the file from which to create a file mapping object.If hFile is INVALID_HANDLE_VALUE, the calling process must also specify a size for the file mapping object [...] In this scenario, CreateFileMapping creates a file mapping object of a specified size that is backed by the system paging file instead of by a file in the file system.=> Either way, memory is allocated on the hard disk, not in the real (physical) RAM. Edit: some mistakes.. Edited September 3, 2007 by zatorg Link to comment Share on other sites More sharing options...
zatorg Posted September 3, 2007 Share Posted September 3, 2007 (edited) And yes you're right, like I said (or haven't I? Amnesia ) this could be done in AutoIt3..Anyway: If one is using small variables and he/she needs to share them between processes, CreateFileMapping() is easy and efficient. If one wants to share large memory regions, I suggest he/she using memory allocation the "normal" way (malloc(), or DllStructCreate() in AutoIt), and then accessing that memory from another process..Just a thought.. Edited September 3, 2007 by zatorg Link to comment Share on other sites More sharing options...
mary Posted September 4, 2007 Share Posted September 4, 2007 (edited) And yes you're right, like I said (or haven't I? Amnesia ) this could be done in AutoIt3..Anyway: If one is using small variables and he/she needs to share them between processes, CreateFileMapping() is easy and efficient. If one wants to share large memory regions, I suggest he/she using memory allocation the "normal" way (malloc(), or DllStructCreate() in AutoIt), and then accessing that memory from another process..Just a thought..at now, we can't share a variable (DllStructCreate) between 2 autoit scripts !maybe, only throw an external dll but not directly between 2 autoit script Edited September 4, 2007 by mary Link to comment Share on other sites More sharing options...
Michel Claveau Posted September 5, 2007 Share Posted September 5, 2007 (edited) Hi!at now, we can't share a variable (DllStructCreate) between 2 autoit scripts !Share variable: no!But exchange data: yes. And exchange data to/from autoit script and other autoit scripts, Python scripts, or Ruby scripts.More exactly, the goal is to share a memory area, and putting/getting data into. Edited September 5, 2007 by Michel Claveau Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now