Windows Shared Memory C ++ and C # implementation

Source: Internet
Author: User

FileMapping is used to put files on disks into the virtual address space of a process, and a region is generated in the virtual address space of the process to "Store" the file, this space is called File View. The system also generates a File Mapping Object (stored in the physical memory) to maintain this ing relationship, in this way, when multiple processes need to read and write the data of that File, their File View actually corresponds to the same File Mapping Object, which can save memory and maintain data synchronization, and achieve data sharing.
Of course, when an application writes data to a file, other processes should not read the data being written. This requires some synchronization operations.
Let's take a look at the specific API.

CreateFileMaping usage:
HANDLE CreateFileMapping (// return the HANDLE of the File Mapping Object
HANDLE hFile, // HANDLE of the file to be mapped
LPSECURITY_ATTRIBUTES lpAttributes, // Security Attribute (only valid for NT and 2000)
DWORD flProtect, // protection Peugeot
DWORD dwMaximumSizeHigh, // store it in the DWORD High Position
File Mapping Object // size
DWORD dwMaximumSizeLow, // store it in the low position of DWORD
File Mapping Object // (usually one of the two parameters is 0)
Lptstr lpName // name of the File Mapping Object.
);
 
1) physical file handle
Any available physical file handle. If you need to create a memory ing unrelated to the physical file, set it to 0 xFFFFFFFF (INVALID_HANDLE_VALUE.
If you need to associate with a physical file, make sure that the access mode when creating your physical file matches the "Protection Settings", such as: the physical file is read-only, an error occurs when memory ing requires read/write. We recommend that you create physical files in exclusive mode.
If INVALID_HANDLE_VALUE is used, you also need to set the size of the memory space to be applied, regardless of whether the physical file handle parameter is valid, so that CreateFileMapping can create a memory space unrelated to the physical file size for you, it exceeds the actual file size. If your physical file is valid and the size parameter is 0, a memory address range with the same size as the physical file is returned. The ing address space of the returned file can be copied, integrated, or named. The initial content is 0.
2) Protection Settings
It is the security setting, but generally it is enough to set NULL. Use the default security configuration. in win2k, if you need to restrict the usage of the application process that shares the memory file ing to the entire network, consider the restrictions.
3) High File Size
32-bit address space, set to 0.
4) shared memory name
The Name can contain the "Global" or "Local" prefix in the Global or session namespace primary file ing. Other parts can contain any character except (). For details, refer to the Kernel Object Name Spaces.
5) corresponding error of GetLastError when CreateFileMapping is called
ERROR_FILE_INVALID if you attempt to create a zero-length file ing, this should be reported
ERROR_INVALID_HANDLE if you find that your namespace maps to the existing memory, mutex, semaphores, and the same name in the critical zone is troublesome
ERROR_ALREADY_EXISTS indicates that the memory space name already exists.
Use the CreateFileMapping function to create a file data handle to be shared, use MapViewOfFile to obtain the shared memory address, and then use the OpenFileMapping function to open the name of the shared file in another process, in this way, different processes can share data.
Below is the C # declaration of the used interface function:
 
[DllImport ("kernel32", SetLastError = true, CharSet = CharSet. Auto)]
Public static extern IntPtr CreateFile (string lpFileName,
Int dwDesiredAccess, int dw1_mode, IntPtr lpSecurityAttributes,
Int dwCreationDisposition, int dwFlagsAndAttributes,
IntPtr hTemplateFile );
 
[DllImport ("kernel32", SetLastError = true, CharSet = CharSet. Auto)]
Public static extern IntPtr CreateFileMapping (IntPtr hFile,
IntPtr lpAttributes, int flProtect,
Int dwMaximumSizeLow, int dwMaximumSizeHigh, string lpName );
 
[DllImport ("kernel32", SetLastError = true)]
Public static extern bool FlushViewOfFile (IntPtr lpBaseAddress,
IntPtr dwNumBytesToFlush );
 
[DllImport ("kernel32", SetLastError = true)]
Public static extern IntPtr MapViewOfFile (
IntPtr hFileMappingObject, int dwDesiredAccess, int dwFileOffsetHigh,
Int dwFileOffsetLow, IntPtr dwNumBytesToMap );
 
[DllImport ("kernel32", SetLastError = true, CharSet = CharSet. Auto)]
Public static extern IntPtr OpenFileMapping (
Int dwDesiredAccess, bool bInheritHandle, string lpName );
 
[DllImport ("kernel32", SetLastError = true)]
Public static extern bool UnmapViewOfFile (IntPtr lpBaseAddress );
 
[DllImport ("kernel32", SetLastError = true)]
Public static extern bool CloseHandle (IntPtr handle );
 
 
 
In this example, a FileMapping created on the Server is named @ "Global \ MyFileMappingObject". In this way, FileMapping with the same name can be opened on the Client, in this way, the Server communicates with the Client. After each Server writes data, we notify the Client that the data is ready and can be read by Message. (We have mentioned the Message before. I will not elaborate on it .)
Take a look at the Code:
Before looking at the specific code, let's take a look at some of the constant definitions used in it:
 
[Flags]
Public enum MapProtection
{
PageNone = 0x00000000,
// Protection-mutually exclusive, do not or
PageReadOnly = 0x00000002,
PageReadWrite = 0x00000004,
PageWriteCopy = 0x00000008,
// Attributes-or-able with protection
SecImage = 0x01000000,
SecReserve = 0x04000000,
SecCommit = 0x08000000,
SecNoCache = 0x10000000,
}
 
Public enum MapAccess
{
FileMapCopy = 0x0001,
FileMapWrite = 0x0002,
FileMapRead = 0x0004,
FileMapAllAccess = 0x001f,
}
 
Public const short FILE_ATTRIBUTE_NORMAL = 0x80;
Public const short INVALID_HANDLE_VALUE =-1;
Public const uint GENERIC_READ = 0x80000000;
Public const uint GENERIC_WRITE = 0x40000000;
Public const uint file_1__read = 0x00000001;
Public const uint CREATE_NEW = 1;
Public const uint CREATE_ALWAYS = 2;
Public const uint OPEN_EXISTING = 3;
 
Windows Message:
 
Public const int WM_USER = 0x0400;
Public const int WM_USER_DATAREADY = WM_USER + 101;
 
 
Below is the Server end:
 
Create MapView:
 
FileHandle = Win32Wrapper. CreateFileMapping (
IntPtr. Zero, IntPtr. Zero,
(Int) (MapProtection. PageReadWrite | MapProtection. SecCommit ),
0, 1000000, Win32Wrapper. MappingFileName );
MappingHandle = Win32Wrapper. MapViewOfFile (
FileHandle, (int) MapAccess. FileMapWrite, 0, 0, new IntPtr (1024 ));
If (mappingHandle = IntPtr. Zero)
{
MessageBox. Show ("Open mapping file failed! ");
}
 
Write information and notify the Client:
 
Private void btnSend_Click (object sender, EventArgs e)
{
// Write message
String message = string. IsNullOrEmpty (this. sendTxt. Text )?
"No message": this. sendTxt. Text;
Byte [] source = Encoding. ASCII. GetBytes (message );
Byte [] msg = new byte [1, 1024];
Array. Copy (source, msg, source. Length );
Marshal. Copy (msg, 0, mappingHandle, msg. Length );
Win32Wrapper. FlushViewOfFile (mappingHandle, new IntPtr (1024 ));
 
// Send message to client
IntPtr handle = GetClientMainFormHandle ();
If (handle! = IntPtr. Zero)
Win32Wrapper. SendMessage (
Handle, Win32Wrapper. WM_USER_DATAREADY,
IntPtr. Zero, IntPtr. Zero );
}
 
Obtain the Client-side main form Handle Code:
 
Private IntPtr GetClientMainFormHandle ()
{
String name =
@ "CSharp. MultiProcess. Communication. FileMappingClient ";
Process process = GetProcessByName (name );
Return process. main1_whandle;
}
 
Private Process GetProcessByName (string processName)
{
Process [] processes = Process. GetProcesses ();
Foreach (Process p in processes)
{
// Just for debug
// This method has some question because
// The visual studio started process name
// Is not same with the release. so yan can
// Close visual studio to test the project.
// Normal, you should use
// If (p. ProcessName = processName)
 
// Debug
If (p. ProcessName. StartsWith (processName ))
Return p;
 
// Release
If (p. ProcessName = processName)
Return p;
}
Return null;
}
 
Disable FileMapping:
 
Private void Server_FormClosing (
Object sender, FormClosingEventArgs e)
{
If (mappingHandle! = IntPtr. Zero)
{
Win32Wrapper. UnmapViewOfFile (mappingHandle );
Win32Wrapper. CloseHandle (mappingHandle );
}
If (fileHandle! = IntPtr. Zero)
Win32Wrapper. CloseHandle (fileHandle );
}
 
Client code:
Receive sent data when a Message is received:
 
Protected override void WndProc (ref Message m)
{
Switch (m. Msg)
{
Case Win32Wrapper. WM_USER_DATAREADY:
RecevieMessage ();
Break;
Default:
Base. WndProc (ref m );
Break;
}
}
 
Private void RecevieMessage ()
{
IntPtr handle = Win32Wrapper. OpenFileMapping (
(Int) MapProtection. PageReadWrite, false,
Win32Wrapper. MappingFileName );
IntPtr mappingFile = Win32Wrapper. MapViewOfFile (
Handle, (int) MapAccess. FileMapRead,
0, 0, new IntPtr (1024 ));
// Marshal. GetLastWin32Error ();
Byte [] msg = new byte [1, 1024];
Marshal. Copy (mappingFile, msg, 0, 1024 );
String message = Encoding. ASCII. GetString (msg );
This. listBox1.Items. Add (message );
Win32Wrapper. UnmapViewOfFile (mappingFile );
Win32Wrapper. CloseHandle (mappingFile );
Win32Wrapper. CloseHandle (handle );
}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.