1. Introduction
in Windows Programs , data is often exchanged between processes for data communication. Win32 API provides many functions that allow us to conveniently and efficiently communicate between processes. Through these functions, we can control data exchange between different processes, it is the same as performing read/write operations on local processes in Win16.
A typical Win16 process can exchange data through the shared memory: (1) process a switches globalalloc (gmem_share ...) the API allocates a certain length of memory. (2) process a transmits the handle returned by the globalalloc function to process B (a logon message is sent). (3) process B calls the globallock function to the handle, use the pointer returned by the globallock function to access data. This method may fail in Win32 because the globallock function returns the memory pointing to process a, because the process uses a virtual address rather than the actual physical address, therefore, this pointer is only related to process a, but not to process B.
This article discusses several methods for communication between processes under Win32. You can use different methods to achieve efficient and reliable program running.
2. memory space management of processes in Windows 95
The communication between Win32 processes is closely related to the memory management of Windows 95. Understanding the memory management of Windows 95 will be of great help to the following program design, next we will discuss the memory space management of processes in Windows 95.
In Win16, all Windows applications share a single address. Any process can share a single address space for this space, any process can perform read and write operations on the memory of other processes in this space, or even access the data of the operating system itself, which may damage the data segments of other programs.Code.
In Win32, each process has its own address space. A Win32 process cannot access the private data of another address. The two processes can use pointers with the same value for addressing, however, only their data is read and written, which reduces mutual interference between processes. On the other hand, each Win32 process has a 4 GB address space, but it does not mean that it actually has 4 GB of physical memory, but only the virtual address space provided by the operating system using the CPU memory allocation function. Generally, most virtual addresses do not have physical memory. Before these addresses are available, the actual physical memory is also provided by the operating system (this process is called "Submit" commit ). Under different circumstances, the physical memory submitted by the system is different, Either ram or Virtual Memory Simulated by the hard disk.
3. inter-process communication in Win32
In Windows 95, to achieve equal data exchange between processes, you can have the following options:
* Use a memory ing File
* Share memory through DLL
* Send the wm_copydata message to another process.
* Call the readprocessmemory and writeprocessmemory functions. You can send the extracted handle called by the globallock (gmem_share,...) function, the pointer returned by the globallock function, and the pointer returned by the virtualalloc function.
3.1. Use the memory ing file to implement Win32 inter-process communication
the memory ing file mechanism in Windows95 allows us to efficiently operate compositions provides a way, it allows us to reserve a memory area in the Win32 process and map the target file to this virtual memory. Synchronization between processes must be considered in program implementation. The specific implementation steps are as follows:
first, we need to call the memory ing API function createfilemapping to create a famous shared memory in the data sending process:
handle createfilemapping (
handle hfile, // handle of the ing file,
// set it to 0xffffffff to create an object shared between processes
lpsecurity_attributes lpfilemappingattributes, // Security Attribute
DWORD flprotect, // protection method
DWORD dwmaximumsizehigh, // object size
DWORD dwmaximumsizelow,
the lpname of the lpctstr // ing file must be named
);
Similar to the virtual memory, the protection mode can be page_readonly or page_readwrite. If multiple processes write access to the same shared memory, they must be synchronized with each other. You can also specify the page_writecopy flag in the ing file to ensure that the original data is not damaged, and allow other processes to freely copy data when necessary.
After creating a file ing object, you can call the mapviewoffile function to map the object to the address space of the current process.
The following describes how to create a famous ing file named mysharedmem with a length of 4096 bytes:
Handle hmysharedmapfile = createfilemapping (handle) 0 xffffffff ),
Null, page_readwrite, 1000 x, "mysharedmem ");
And map the cache area View:
Lpstr pszmysharedmapview = (lpstr) mapviewoffile (hmysharedmapfile,
File_map_read | file_map_write, 0, 0 );
When other processes Access shared objects, they need to obtain the Object Name and call the openfilemapping function.
Handle hmysharedmapfile = openfilemapping (file_map_write,
False, "mysharedmem ");
Once another process obtains the handle of the ing object, it can call the mapviewoffile function as the creation process to map the object view. You can use this object view to read and write data to achieve data communication.
After a user process stops using shared memory, call the unmapviewoffile function to cancel the view in the address space:
If (! Unmapviewoffile (pszmysharedmapview ))
{Afxmessagebox ("cocould not unmap view of file ");}
3.2 use the shared memory DLL
The shared data dll allows a process to read and write data in a way similar to Windows 3.1 DLL sharing data. Multiple processes can perform data operations on the shared data DLL to share data. To create shared memory in Win32, perform the following steps:
First, create a famous data zone. This uses the data_seg Pragma macro in Visual C ++. When using the data_seg Pragma macro, you must note the data initialization:
# Pragma data_seg ("mysec ")
Char myshareddata [4096] = {0 };
# Pragma data_seg ()
Then, set the sharing attribute for the famous data zone in the user's def file.
Library Test
Data read write
Sections
. Mysec read write shared
In this way, each DLL-attached process will receive its own data copy, and the data changes of one process will not be reflected in the data of other processes.
Output data locally in the def file. The following def file items demonstrate how to output myshareddata in the form of constant variables.
Exports
Myshareddata constant
At last, shared data is referenced by external variables in the application (process.
Extern _ export "C" {char * myshareddata [];}
When using this variable in a process, pay attention to indirect reference.
M_pstatic = (cedit *) getdlgitem (idc_shared );
M_pstatic-> Getline (0, * myshareddata, 80 );
3.3. wm_copydata used to transmit read-only data
The wm_copydata message in Win32 can be used to transmit read-only data. The main purpose of this message is to allow the transfer of read-only data between processes. During wm_copydata message transmission, Windows95 does not provide an inherited synchronization mode. We recommend that you use the sendmessage function in the SDK documentation. The receiver does not return the message before the data copy is completed, so that the sender cannot delete or modify the data:
Sendmessage (hwnd, wm_copydata, wparam, lparam );
Wparam is set to the handle of the window containing data. Lparam points to a copydatastruct structure:
Typedef struct tagcopydatastruct {
DWORD dwdata; // user-defined data
DWORD cbdata; // data size
Pvoid lpdata; // pointer to data
} Copydatastruct;
This structure is used to define user data.
3.4 directly call the readprocessmemory and writeprocessmemory functions to implement inter-process communication
By calling the readprocessmemory and writeprocessmemory functions, you can achieve inter-process communication by using methods similar to Windows, allocate a piece of memory in the sending process to store data, and call the globalalloc or virtualalloc functions for implementation:
PAPP-> m_hglobalhandle = globalalloc (gmem_share, 1024 );
You can get the pointer address:
PAPP-> mpszglobalhandleptr = (lpstr) globallock
(PAPP-> m_hglobalhandle );
In the receiving process, use the open handle of the process to be affected by the user. To read and write another process, the OpenProcess function should be called as follows:
Handle htargetprocess = OpenProcess (
Standard_rights_required |
Process_vm_reda |
Process_vm_write |
Process_vm_operation, // access permission
False, // inheritance relationship
Dwprocessid); // process ID
To ensure that the OpenProcess function is successfully called, the processes affected by the user must be created by the above sign.
Once the user obtains a valid handle of a process, he can call the readprocessmemory function to read the memory of the process:
Bool readprocessmemory (
Handle hprocess, // process pointer
Lpcvoid lpbaseaddress, // The first address of the data block
Lpvoid lpbuffer, // buffer required to read data
DWORD cbread, // number of bytes to read
Lpdword lpnumberofbytesread
);
The same handle can also be used to write the memory of the process:
Bool writeprocessmemory (
Handle hprocess, // process pointer
Lpvoid lpbaseaddress, // The first address to be written
Lpvoid lpbuffer, // buffer address
DWORD cbwrite, // number of bytes to write
Lpdword lpnumberofbyteswritten
);
Read and Write Data in the shared memory of another process as follows:
Readprocessmemory (handle) htargetprocess,
(Lpstr) lpsz, m_strglobal.getbuffer (_ max_field ),
_ Max_field, & CB );
Writeprocessmemory (handle) htargetprocess,
(Lpstr) lpsz, (lpstr) stars,
M_strglobal.getlength (), & CB );
4. send and receive messages between processes
In practical applications, processes need to send and receive Windows messages to notify them to communicate with each other. The sender sends a message to notify the recipient, after receiving the message from the sender, the receiver can perform read/write operations on the memory.
In the program design, we use Windows to register a message for message transmission. First, we register the message during the initialization process of the sending process:
M_nmsgmapped =: registerwindowsmessage ("mapped ");
M_nmsghandle =: registerwindowsmessage ("handle ");
M_nmsgshared =: registerwindowsmessage ("shared ");
Send a message to the receiving process while the program is running:
Cwnd * pwndrecv = findwindow (lpclassname, "receive ");
Pwndrecv-> sendmessage (m_msgmapped, 0, 0 );
Pwndrecv-> sendmessage (m_nmsghandle,
(Uint) getcurrentprocessid (), (long) PAPP-> m_hglobalhandle );
Pwndrecv-> sendmessage (m_nmsgshared, 0, 0 );
You can send the wm_copydata message as follows:
Static copydatastruct CDs; // data stored by the user
Pwnd-> sendmessage (wm_copydata, null, (long) & CDs );
Message registration is also required for recipient process initialization:
Unit crecvapp: m_nmsgmapped =: registerwindowsmessage ("mapped ");
Unit crecvapp: m_nmsghandle =: registerwindowsmessage ("handle ");
Unit crecvapp: m_nmsgshared =: registerwindowsmessage ("shared ");
The message ing function is as follows:
On_registered_massage (crecvapp: m_nmsgmapped, onregmsgmapped)
On_registered_massage (crecvapp: m_nmsghandle, onregmsghandle)
On_registered_massage (crecvapp: m_nmsgshared, onregmsgshared)
In these message functions, we can use the above technology to read and write data in the receiving process.
5. Conclusion
From the above analysis, we can see that the memory management of Windows 95 is much different from that of Windows 3.x, and there are strict restrictions on inter-process communication. This ensures that any faulty program cannot accidentally write data into the user's address space, while the user can flexibly communicate data between processes according to the actual situation, in this regard, Windows 95 enhances the robustness of applications.
References:
1. David J. kruglinski, Visual C ++ technology insider, Beijing: Tsinghua University Press, 1995.
2. Microsoft co. Visual C ++ 5.0 on line help.