c#读写共享内存操作函数封装 淮安七夕软件有限公司
来源:互联网 发布:金蝶软件数据库 编辑:程序博客网 时间:2024/06/11 03:50
c#共享内存操作相对c++共享内存操作来说原理是一样,但是c#会显得有点复杂。
现把昨天封装的读写共享内存封装的函数记录下来,一方面希望给需要这块的有点帮助,另一方面则是做个备份吧。
/// <summary> /// 写共享内存 /// </summary> /// <param name="structSize">需要映射的文件的字节数量</param> /// <param name="obj">映射对象(简单类型、结构体等)</param> /// <param name="fileName">文件映射对象的名称</param> /// <param name="windowName">发送消息的窗口句柄</param> /// <param name="Msg">发送消息</param> /// <returns></returns> public static int WriteToMemory(uint structSize, Object obj, string fileName, string windowName, uint Msg) { IntPtr hShareMemoryHandle = IntPtr.Zero; IntPtr hVoid = IntPtr.Zero; //判断参数的合法性 if (structSize > 0 && fileName.Length > 0) { hShareMemoryHandle = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)structSize, fileName); if (hShareMemoryHandle == IntPtr.Zero) { //创建共享内存失败,记log MessageBox.Show("创建共享内存失败"+publicInfo.GetLastError().ToString()); return -2; } else { if (ERROR_ALREADY_EXISTS == GetLastError()) { //共享内存已经存在,记log MessageBox.Show("共享内存已经存在"); return -3; } } hVoid = MapViewOfFile(hShareMemoryHandle, FILE_MAP_WRITE, 0, 0, structSize); if (hVoid == IntPtr.Zero) { CloseHandle(hShareMemoryHandle); //文件映射失败,记log MessageBox.Show("文件映射失败"); return -4; } Marshal.StructureToPtr(obj, hVoid, false); //发送消息,通知接收 IntPtr handle = FindWindow(null, windowName.Trim()); if (handle == IntPtr.Zero) { //查找窗口失败,记log MessageBox.Show("查找窗口失败"); return -5; } else { if (PostMessage(handle, (uint)Msg, 0, 0)) { //发送消息成功 //MessageBox.Show("写共享内存,通知发送消息成功"); } } } else { //参数不合法,记log MessageBox.Show("共享内存已经存在"); return -1; } return 0; }写共享内存函数并没有什么需要说明,完全按照:
创建共享内存文件(CreateFileMapping)---》映射文件视图到调用进程的地址空间(MapViewOfFile)---》写数据到共享内存(Marshal.StructureToPtr)----》发送消息通知需要读共享内存的窗口(PostMessage)
/// <summary> /// 读共享内存 /// </summary> /// <param name="structSize">需要映射的文件的字节数量</param> /// <param name="type">类型</param> /// <param name="fileName">文件映射对象的名称</param> /// <returns>返回读到的映射对象</returns> public static Object ReadFromMemory(uint structSize, Type type, string fileName) { IntPtr hMappingHandle = IntPtr.Zero; IntPtr hVoid = IntPtr.Zero; hMappingHandle = OpenFileMapping((uint)FILE_MAP_READ, false, fileName); if (hMappingHandle == IntPtr.Zero) { //打开共享内存失败,记log MessageBox.Show("打开共享内存失败:" + publicInfo.GetLastError().ToString()); return null; } hVoid = MapViewOfFile(hMappingHandle, FILE_MAP_READ, 0, 0, structSize); if (hVoid == IntPtr.Zero) { //文件映射失败,记log MessageBox.Show("文件映射失败——读共享内存"); return null; } Object obj = Marshal.PtrToStructure(hVoid, type); if (hVoid != IntPtr.Zero) { UnmapViewOfFile(hVoid); hVoid = IntPtr.Zero; } if (hMappingHandle != IntPtr.Zero) { CloseHandle(hMappingHandle); hMappingHandle = IntPtr.Zero; } return obj; }
读共享内存,上边代码是一种方式,这里是传入一个Type类型,这样就确保可以传入任何类型。当读到共享内存的数据时,采用
public static object PtrToStructure(IntPtr ptr, Type structureType);
函数,把非托管指针(共享内存获得的指针)转换为需要转换的Type类型的对象。如果需要的话,可以通过显示类型转换转换为需要的类型(例子继续看)。
/// <summary> /// 读共享内存 /// </summary> /// <param name="structSize">需要映射的文件的字节数量</param> /// <param name="type">类型</param> /// <param name="fileName">文件映射对象的名称</param> /// <returns>返回读到的映射字节数据</returns> public static byte[] ReadFromMemory(uint structSize, Type type, string fileName) { IntPtr hMappingHandle = IntPtr.Zero; IntPtr hVoid = IntPtr.Zero; hMappingHandle = OpenFileMapping((uint)FILE_MAP_READ, false, fileName); if (hMappingHandle == IntPtr.Zero) { //打开共享内存失败,记log MessageBox.Show("打开共享内存失败:" + publicInfo.GetLastError().ToString()); return null; } hVoid = MapViewOfFile(hMappingHandle, FILE_MAP_READ, 0, 0, structSize); if (hVoid == IntPtr.Zero) { //文件映射失败,记log MessageBox.Show("文件映射失败——读共享内存"); return null; } //Object obj = Marshal.PtrToStructure(hVoid, type); byte[] bytes = new byte[structSize]; Marshal.Copy(hVoid, bytes, 0, bytes.Length); if (hVoid != IntPtr.Zero) { UnmapViewOfFile(hVoid); hVoid = IntPtr.Zero; } if (hMappingHandle != IntPtr.Zero) { CloseHandle(hMappingHandle); hMappingHandle = IntPtr.Zero; } return bytes; }此代码和第一个读共享内存不同的是,采用byte[]读需要的共享内存。使用托管类中的Copy来转换指针。
byte[] bytes = new byte[structSize];Marshal.Copy(hVoid, bytes, 0, bytes.Length);
调用简单例子部分代码如下:
注:passiveInfo是NotifyInfo结构体对象。
写共享内存:
int iRet = publicInfo.WriteToMemory((uint)Marshal.SizeOf(passiveInfo),(Object)passiveInfo, "memName","FormMsg",(uint)publicInfo.WM_NOTIFY);
读共享内存:
第一种情况调用:
passiveInfo = (NotifyPassiveInfo)publicInfo.ReadFromMemory((uint)Marshal.SizeOf(passiveInfo), typeof(NotifyPassiveInfo), publicInfo.SN_PASSIVEINFO);第二种情况调用:
byte[] bytes = publicInfo.ReadFromMemory((uint)Marshal.SizeOf(passiveInfo), "memName");passiveInfo = (NotifyInfo)BytesToStuct(bytes, typeof(NotifyInfo));
0 0
- c#读写共享内存操作函数封装 淮安七夕软件有限公司
- c#读写共享内存操作函数封装
- 七夕毛巾行业生产管理软件实现毛巾生产流程的无纸化操作为毛巾行业发展提动力 淮安七夕软件有限公司
- C#读写内存操作方式
- 共享内存操作类 c#
- 共享内存操作类 C#
- C# 共享内存操作类
- C# 共享内存操作类
- 进程间共享内存操作简易封装
- C#读写EXCEL操作的简单封装
- shm*()--共享内存操作函数
- 共享内存和操作共享内存几个函数的用法
- 共享内存操作类(C#源码)
- 共享内存操作类(C#源码)
- 共享内存操作类(C#源码)
- 共享内存操作类(C#源码)
- C#共享内存操作类(含源码)
- 共享内存操作类(C#源码)[转]
- 远程连接mysql数据库
- 防止界面窗口不能操作
- Highcharts写时序图(大数据量交换)
- AOJ-AHU-OJ-64 数字三角形
- 4--4数组做数据成员(扩展2,3)
- c#读写共享内存操作函数封装 淮安七夕软件有限公司
- Comet:基于 HTTP 长连接的“服务器推”技术
- border-radius(圆角)的几点说明
- iOS Block详解4
- 工厂和策略
- web.xml/mime-mapping
- C:文件结构“图”[openjudge1777]
- C++内存管理
- ubuntu 下eclipse开发cocos2dx环境