using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Threading; namespace Dll { public class ShareMem { [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam); [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName); [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr OpenFileMapping(int dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpName); [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr MapViewOfFile(IntPtr hFileMapping, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap); [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] public static extern bool UnmapViewOfFile(IntPtr pvBaseAddress); [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] public static extern bool CloseHandle(IntPtr handle); [DllImport("kernel32", EntryPoint = "GetLastError")] public static extern int GetLastError(); const int ERROR_ALREADY_EXISTS = 183; const int FILE_MAP_COPY = 0x0001; const int FILE_MAP_WRITE = 0x0002; const int FILE_MAP_READ = 0x0004; const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004; const int PAGE_READONLY = 0x02; const int PAGE_READWRITE = 0x04; const int PAGE_WRITECOPY = 0x08; const int PAGE_EXECUTE = 0x10; const int PAGE_EXECUTE_READ = 0x20; const int PAGE_EXECUTE_READWRITE = 0x40; const int SEC_COMMIT = 0x8000000; const int SEC_IMAGE = 0x1000000; const int SEC_NOCACHE = 0x10000000; const int SEC_RESERVE = 0x4000000; const int INVALID_HANDLE_VALUE = -1; IntPtr m_hSharedMemoryFile = IntPtr.Zero; IntPtr m_pwData = IntPtr.Zero; IntPtr m_pwDataWrite = IntPtr.Zero; IntPtr m_pwDataRead = IntPtr.Zero; bool m_bAlreadyExist = false; bool m_bInit = false; long m_MemSize = 0; int m_length = 0; int m_count = 0; const int infoSize = 50; Semaphore semRead; Semaphore semWrite; Semaphore semWriteLength; public ShareMem() { } ~ShareMem() { Close(); } /// /// 初始化共享内存 /// /// 共享内存名称 /// 共享内存大小 /// public int Init(string strName, long lngSize) { if (lngSize <= 0 || lngSize > 0x00800000) lngSize = 0x00800000; m_MemSize = lngSize; if (strName.Length > 0) { //创建内存共享体(INVALID_HANDLE_VALUE) m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)lngSize, strName); if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建 { m_bAlreadyExist = true; m_hSharedMemoryFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, strName); } if (m_hSharedMemoryFile == IntPtr.Zero) { m_bAlreadyExist = false; m_bInit = false; return 2; //创建共享体失败 } else { if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建 { m_bAlreadyExist = true; } else //新创建 { m_bAlreadyExist = false; } } //--------------------------------------- //创建内存映射 m_pwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, (uint)lngSize); m_pwDataWrite = m_pwData; m_pwDataRead = (IntPtr)(m_pwData.GetHashCode() + infoSize); if (m_pwData == IntPtr.Zero) { m_bInit = false; CloseHandle(m_hSharedMemoryFile); return 3; //创建内存映射失败 } else { m_bInit = true; if (m_bAlreadyExist == false) { //初始化 } } //---------------------------------------- } else { return 1; //参数错误 } SetSemaphore(); if (m_bAlreadyExist == false) { WriteLengthAndCount(0, 0); } return 0; //创建成功 } /// /// 关闭共享内存 /// public void Close() { if (m_bInit) { UnmapViewOfFile(m_pwData); CloseHandle(m_hSharedMemoryFile); } } public bool SetSemaphore() { try { semRead = Semaphore.OpenExisting("ReadShareMemory"); semWrite = Semaphore.OpenExisting("WriteShareMemory"); semWriteLength = Semaphore.OpenExisting("WriteLengthShareMemory"); } catch (Exception) { semRead = new Semaphore(0, 1, "ReadShareMemory"); semWrite = new Semaphore(1, 1, "WriteShareMemory"); semWriteLength = new Semaphore(1, 1, "WriteLengthShareMemory"); } return true; } /** public int ReadLength() { Byte[] bytData = new Byte[infoSize]; if (infoSize > m_MemSize) return 2; //超出数据区 if (m_bInit) { Marshal.Copy(m_pwData, bytData, 0, infoSize); } else { return 1; //共享内存未初始化 } String str = System.Text.Encoding.Unicode.GetString(bytData).Trim('/0'); m_length = System.Convert.ToInt32(str); return 0; //读成功 } public int WriteLength(int length) { semWriteLength.WaitOne(); if (infoSize > m_MemSize) return 2; //超出数据区 String strLength = System.Convert.ToString(length); Byte[] bytData = System.Text.Encoding.Unicode.GetBytes(strLength); if (m_bInit) { Marshal.Copy(bytData, 0, m_pwData, bytData.Length); } else { semWriteLength.Release(); return 1; //共享内存未初始化 } semWriteLength.Release(); return 0; } **/ public int ReadLengthAndCount() { Byte[] bytData = new Byte[infoSize]; if (infoSize > m_MemSize) return 2; //超出数据区 if (m_bInit) { Marshal.Copy(m_pwData, bytData, 0, infoSize); } else { return 1; //共享内存未初始化 } String str = System.Text.Encoding.Unicode.GetString(bytData).Trim('/0'); String[] strs = System.Text.RegularExpressions.Regex.Split(str, "/0"); m_length = System.Convert.ToInt32(strs[0]); m_count = System.Convert.ToInt32(strs[1]); return 0; //读成功 } public int WriteLengthAndCount(int length, int count) { semWriteLength.WaitOne(); if (infoSize > m_MemSize) return 2; //超出数据区 String strLengthAndCount = System.Convert.ToString(length) + "/0" + System.Convert.ToString(count); Byte[] bytData = System.Text.Encoding.Unicode.GetBytes(strLengthAndCount); if (m_bInit) { /** Byte[] byteZero = new Byte[infoSize]; for (int i = 0; i < infoSize; i++) { byteZero[i] = (Byte)'/0'; } Marshal.Copy(byteZero, 0, m_pwData, infoSize); * **/ Marshal.Copy(bytData, 0, m_pwData, bytData.Length); } else { semWriteLength.Release(); return 1; //共享内存未初始化 } semWriteLength.Release(); return 0; } /// /// 读数据 /// /// 数据 /// 起始地址 /// 个数 /// public int Read(ref byte[] bytData) { ReadLengthAndCount(); if (m_length > m_MemSize) return 2; //超出数据区 if (m_bInit) { Marshal.Copy(m_pwDataRead, bytData, 0, m_length); } else { return 1; //共享内存未初始化 } return 0; //读成功 } /// /// 写数据 /// /// 数据 /// 起始地址 /// 个数 /// public int Write(byte[] bytData, int lngSize) { semWrite.WaitOne(); ReadLengthAndCount(); if (m_length + lngSize > m_MemSize) return 2; //超出数据区 if (m_bInit) { m_pwDataWrite = (IntPtr)(m_pwData.GetHashCode() + m_length + infoSize); Marshal.Copy(bytData, 0, m_pwDataWrite, lngSize); m_length += lngSize; m_count++; } else { semWrite.Release(); return 1; //共享内存未初始化 } WriteLengthAndCount(m_length, m_count); semWrite.Release(); return 0; //写成功 } public int GetLength() { ReadLengthAndCount(); return this.m_length; } public int GetCount() { ReadLengthAndCount(); return this.m_count; } public int Clear() { ReadLengthAndCount(); if (infoSize + m_length > m_MemSize) return 2; //超出数据区 if (m_bInit) { Byte[] byteZero = new Byte[infoSize + m_length]; for (int i = 0; i < infoSize; i++) { byteZero[i] = (Byte)'/0'; } Marshal.Copy(byteZero, 0, m_pwData, infoSize + m_length); m_pwDataWrite = m_pwData; m_length = 0; m_count = 0; WriteLengthAndCount(0, 0); } return 0; } } } 调用 public Form1() { //InitializeComponent(); //Start(); if (MemDB.Init("hello world", 10240) != 0) { MessageBox.Show("初始化失败"); } else { try { Byte[] data = System.Text.Encoding.Unicode.GetBytes("hello world"); MemDB.Write(data, data.Length); } catch (Exception) { MessageBox.Show("Error in WriteStr"); } } int currentLength = MemDB.GetLength(); Byte[] rd = new Byte[currentLength]; MemDB.Read(ref rd); MessageBox.Show(System.Text.Encoding.Unicode.GetString(rd) + "长度:" + MemDB.GetLength().ToString()); } public static Dll.ShareMem MemDB = new Dll.ShareMem();