VC++的共享内存操作代码实现起来相对比较容易,但是用C#语言来实现,就有一定难度,由于工作需要,把以前VC开发的共享内存代码要用C#实现,别说,还费了不少周折,毕竟C#操作API函数和地址指针不是那么直接,还好,总算完成了,效果还不错。
共享内存操作类:
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Runtime.InteropServices;
- namespace ShareMemLib
- {
- 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;
- bool m_bAlreadyExist = false;
- bool m_bInit = false;
- long m_MemSize=0;
- public ShareMem()
- {
- }
- ~ShareMem()
- {
- Close();
- }
- /// <summary>
- /// 初始化共享内存
- /// </summary>
- /// <param name="strName">共享内存名称</param>
- /// <param name="lngSize">共享内存大小</param>
- /// <returns></returns>
- 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 (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_WRITE, 0, 0, (uint)lngSize);
- if (m_pwData == IntPtr.Zero)
- {
- m_bInit = false;
- CloseHandle(m_hSharedMemoryFile);
- return 3; //创建内存映射失败
- }
- else
- {
- m_bInit = true;
- if (m_bAlreadyExist == false)
- {
- //初始化
- }
- }
- //----------------------------------------
- }
- else
- {
- return 1; //参数错误
- }
- return 0; //创建成功
- }
- /// <summary>
- /// 关闭共享内存
- /// </summary>
- public void Close()
- {
- if (m_bInit)
- {
- UnmapViewOfFile(m_pwData);
- CloseHandle(m_hSharedMemoryFile);
- }
- }
- /// <summary>
- /// 读数据
- /// </summary>
- /// <param name="bytData">数据</param>
- /// <param name="lngAddr">起始地址</param>
- /// <param name="lngSize">个数</param>
- /// <returns></returns>
- public int Read(ref byte[] bytData, int lngAddr, int lngSize)
- {
- if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区
- if (m_bInit)
- {
- Marshal.Copy(m_pwData, bytData, lngAddr, lngSize);
- }
- else
- {
- return 1; //共享内存未初始化
- }
- return 0; //读成功
- }
- /// <summary>
- /// 写数据
- /// </summary>
- /// <param name="bytData">数据</param>
- /// <param name="lngAddr">起始地址</param>
- /// <param name="lngSize">个数</param>
- /// <returns></returns>
- public int Write(byte[] bytData, int lngAddr, int lngSize)
- {
- if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区
- if (m_bInit)
- {
- Marshal.Copy(bytData, lngAddr, m_pwData, lngSize);
- }
- else
- {
- return 1; //共享内存未初始化
- }
- return 0; //写成功
- }
- }
- }
- 测试例程:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Text;
- using System.Windows.Forms;
- using ShareMemLib;
- namespace YFShareMem
- {
- public partial class frmShareMem : Form
- {
- ShareMem MemDB=new ShareMem();
- public frmShareMem()
- {
- InitializeComponent();
- }
- private void btnOpen_Click(object sender, EventArgs e)
- {
- if (MemDB.Init("YFMemTest", 10240) != 0)
- {
- //初始化失败
- MessageBox.Show("初始化失败");
- }
- else
- {
- btnOpen.Enabled = false;
- chkWrite.Enabled = true;
- tmrTime.Enabled = true;
- }
- }
- private void tmrTime_Tick(object sender, EventArgs e)
- {
- byte[] bytData = new byte[16];
- int intRet = MemDB.Read(ref bytData, 0, 16);
- lstData.Items.Clear();
- if (intRet == 0)
- {
- for (int i = 0; i < 16; i++)
- {
- lstData.Items.Add(bytData[i].ToString());
- }
- if (chkWrite.Checked)
- {
- bytData[0]++;
- bytData[1] += 2;
- if (bytData[0] > 200) bytData[0] = 0;
- if (bytData[1] > 200) bytData[1] = 0;
- MemDB.Write(bytData, 0, 16);
- }
- }
- }
- }
- }
本文转自yefanqiu51CTO博客,原文链接:http://blog.51cto.com/yfsoft/323427,如需转载请自行联系原作者