Http://blog.codingnow.com/2005/10/interprocess_communications.html
There are many ways to implement interprocess communication under Windows, such as sockets, pipes, Mailboxes (mailslot), and so on. But the most basic and direct thing is to use memory sharing. Other methods will eventually be used to bypass this.
It is conceivable that if there is only one copy of physical memory, it is one of the most efficient data exchange methods to map to the respective virtual address space in different processes, and each process can read the same data. Let's discuss how to implement it.
Shared within Windows is implemented with filemapping. We can create a memory file mapping object with CreateFileMapping, createfilemapping this API will create a kernel object for mapping files to memory. Here, we do not need an actual file, so there is no need to call CreateFile to create a file, hfile This parameter can be filled in invalid_handle_value. However, the file length is required. Windows supports files up to 64bit, but here, our demand must not exceed 4G, Dwmaximumsizehigh must be 0, the length of the dwmaximumsizelow can be filled. Then call MapViewOfFile to map to the virtual address of the current process. Once you run out of shared memory, call UnmapViewOfFile to reclaim the memory address space.
It makes sense for Windows to separate the createfilemapping and MapViewOfFile two APIs. This is because it allows you to map a file that is more than 4G, and the address space is only 4 G (in fact, the average user's program only uses 2G), MapViewOfFile can specify the file's Offset and only part of the map.
In createfilemapping the last parameter Pszname fill in a name, then other processes can use this name to call OpenFileMapping to open the Filemapping object, in the new process mapping. However, the method of using the contract string does not seem elegant.
An elegant approach is to use DuplicateHandle to replicate a Filemapping object in a new process, and then find a way to notify the Handle of a new process, such as passing it through a message.
If the two processes that need to share memory are parent-child relationships, then we can notify Filemapping's Handle without a message-passing way. The parent process can pass the Handle of filemapping directly to the child process in a way that inherits Handle. Of course, you should set the properties that can be inherited when createfilemapping.
That's about it:
Security_attributes sa;
Sa.nlength=sizeof (SA);
Sa.lpsecuritydescriptor=null;
Sa.binherithandle=true;
Handle=createfilemapping (Invalid_handle_value,&sa,page_readwrite,0,size,null);
Thus, when CreateProcess, if the binherithandles parameter is TRUE, all kernel objects that have inheritable properties are copied into the child process.
Note: The inheritance of kernel objects is to create child processes in CreateProcess, but before the main thread of a child process is active, the kernel scans all kernel objects in the current process, checks for those with inheritable properties, and then copies one copy to the child process with DuplicateHandle. Because it is a kernel object, there is only one copy in the kernel, all just the reference count plus one, and the parent and child processes must be the same for the Handle of the same kernel object.
The process of copying a kernel object is done internally by CreateProcess, and we can safely pass the object Handle (the same as the child process) through the command line to the child process. Alternatively, it can be passed with an environment variable.
It is worth noting that the child process needs to CloseHandle minus the reference count as soon as the Filemapping object is exhausted.
Note:
When CreateProcess is called, pszCommandLine cannot directly fill in a non-modifiable string. For example:
CreateProcess ("Test.exe", "Test Argument",...);
This is wrong, because "test argument" is compiled by the compiler into the non-modifiable data segment. The correct method is:
Char cmdline[]= "Test argument";
CreateProcess ("Test.exe", CmdLine,...);
This way, the command line string is placed on the stack and can be read and written.
CreateProcess The penultimate parameter needs to fill in a startupinfow structure, which is complex and often cumbersome to fill. We can copy the structure of a parent process and modify it as appropriate. The method is:
Startupinfo si={sizeof (SI)};
Process_information Pi;
Getstartupinfo (&SI);
CreateProcess (...,&si,& pi);
Here, the first length information of the STARTUPINFO structure should usually be filled in, guaranteeing getstartupinfo (&SI); The correct execution.
Go Inter-process communication and data sharing under Windows