通过进程协作显示图像-C#

news2024/11/27 7:28:37

前言

如果一个软件比较复杂或者某些情况下需要拆解,可以考试将软件分解成两个或多个进程,但常规的消息传递又不能完全够用,使用消息+共享内存,实现图像传递,当然性能这个方面我并没有测试,仅是一种解决思路吧。

一、效果展示

1、调用方

2、被调用方

二、实现代码

1、主调打开调用进程

主要是为了拿到Handle,为发送消息函数提供操作句柄。

2、创建共享内存

        /// <summary>
        /// 创建共享内存
        /// </summary>
        /// <returns>0=创建成功;1=创建共享体失败;2=打开失败;3=印射失败; 4=共享内存命名错误</returns>
        public int CreateMemory()
        {
            if (MemSize <= 0) MemSize = 0x00800000;
            if (ShareName.Length > 0)
            {
                //创建内存共享体(INVALID_HANDLE_VALUE)
                m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)MemSize, ShareName);
                if (m_hSharedMemoryFile == IntPtr.Zero)
                {
                    m_bAlreadyExist = false;
                    m_bInit = false;
                    MemPtr = IntPtr.Zero;
                    return 1; //创建共享体失败
                }
                else
                {
                    if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建
                    {
                        m_bAlreadyExist = true;
                        CloseHandle(m_hSharedMemoryFile);
                        m_hSharedMemoryFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, ShareName);
                        if (m_hSharedMemoryFile == null)
                        {
                            MemPtr = IntPtr.Zero;
                            return 2;//打开共享内存失败
                        }
                    }
                    else                                         //新创建
                    {
                        m_bAlreadyExist = false;
                    }
                }
                //创建内存映射
                m_rwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, (uint)MemSize);
                if (m_rwData == IntPtr.Zero)
                {
                    m_bInit = false;
                    CloseHandle(m_hSharedMemoryFile);
                    MemPtr = IntPtr.Zero;
                    return 3; //创建内存映射失败
                }
                else
                {
                    m_bInit = true;
                    MemPtr = m_rwData;
                }
            }
            else
            {
                return 4; //参数错误
            }
            return 0;     //创建成功
        }

3、读取本地图像并写图像数据到共享内存中

 MyAlgoProcessNet.HImage hImage = new MyAlgoProcessNet.HImage(fileName);

 IntPtr prt = hImage.GetImagePointer1(out string type, out imageData.Widht, out imageData.Height);
 imageData.dataLength = imageData.Widht * imageData.Height;
 byte[] datas = new byte[imageData.dataLength];
 Marshal.Copy(prt, datas, 0, imageData.dataLength);
 int pos = Marshal.SizeOf(imageData);
 share1.WriteToMemory(imageData);

 //写共享内存
 if (share1.WriteBytes(datas, pos + 1) == 0)
 {
     WriteMsg("share1写入共享内存成功");
 }
 else
 {
     WriteMsg("share1写入共享内存失败!!");
 }



   public int WriteBytes(byte[] datas, int pos = -1)
   {
       if (IntPtr.Zero == MemPtr)
       {
           return -1;
       }
       if (pos == -1)
       {
           Marshal.Copy(datas, 0, MemPtr, datas.Length);
       }
       else
       {
           IntPtr offPtr = IntPtr.Add(MemPtr, pos);
           Marshal.Copy(datas, 0, offPtr, datas.Length);
       }

       return 0;
   }

4、通知读取数据

private void SendMsg2(string msg)
{
    // 获取目标进程句柄

    IntPtr hWnd = process.MainWindowHandle;

    // 封装消息

    byte[] sarr = System.Text.Encoding.Default.GetBytes(msg);

    int len = sarr.Length;

    COPYDATASTRUCT cds2;

    cds2.dwData = (IntPtr)0;

    cds2.cbData = len + 1;

    cds2.lpData = msg;

    // 发送消息
    WriteMsg(msg + " Start");
    SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, ref cds2);
    WriteMsg(msg + " End");
}

5、被调用方关联消息处理函数

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
            if (hwndSource != null)
            {
                IntPtr handle = hwndSource.Handle;
                hwndSource.AddHook(new HwndSourceHook(WndProc));
            }
        }

6、被调用方处理图像数据

        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == WM_COPYDATA)
            {
                WriteInfo(1, "WndProc Start");
                COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam,
                typeof(COPYDATASTRUCT)); // 接收封装的消息
                string rece = cds.lpData; // 获取消息内容
                                          // 自定义行为
                                          //  Console.WriteLine(rece);

                if (rece == "Read")
                {
                    Task.Run(() =>
                    {
                        //读共享内存
                        // datastruct = (MemoryClass)shareMemory.ReadFromMemory(typeof(MemoryClass));
                        // WriteInfo(1, $"读取数据:{datastruct.bianliang1},{datastruct.bianliang2},{datastruct.bianliang3}");

                        imageData = (ImageData)shareMemory.ReadFromMemory(typeof(ImageData));

                        int ShareSize = Marshal.SizeOf(imageData);
                        byte[] datas = shareMemory.ReadByteFromMemory(imageData.dataLength, ShareSize + 1);
                        HImage hImage = new HImage();
                        using (PinnedObject pinnedObject = new PinnedObject(datas))
                        {
                            hImage.GenImage1("byte", imageData.Widht, imageData.Height, pinnedObject.Pointer);
                        }
                        // hImage.GenImage1(imageData.DataType, imageData.Widht, imageData.Height, imageData.dataPrt);
                        ImgControl.HalconWindow.AttachBackgroundToWindow(hImage);
                        WriteInfo(1, "图像处理完成");
                    });
                }
                // Thread.Sleep(2000);
                WriteInfo(2, rece);
                if (rece.Equals("Close"))
                {
                    this.Close();
                }
            }
            return hwnd;
        }

7、共享内存操作

  internal class ShareMemory
  {
      [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();

      private const int INVALID_HANDLE_VALUE = -1;
      private const int ERROR_ALREADY_EXISTS = 0xB7;//183
      private const int PAGE_READWRITE = 0x04;
      private const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004;
      private const int FILE_MAP_READ = 0x0004;
      private const int FILE_MAP_WRITE = 0x0002;

      private IntPtr m_hSharedMemoryFile = IntPtr.Zero;
      private IntPtr m_rwData = IntPtr.Zero;
      private bool m_bAlreadyExist = false;
      private bool m_bInit = false;

      private string ShareName { get; set; } //共享内存的名字
      private long MemSize { get; set; }//共享内存大小
      private IntPtr MemPtr { get; set; }//共享内存印射地址

      /// <summary>
      /// 共享内存初始化
      /// </summary>
      /// <param name="MemName">共享内存名字</param>
      /// <param name="MemSize">共享内存大小</param>
      public ShareMemory(string MemName, long Size)
      {
          ShareName = MemName;
          MemSize = Size;
          MemPtr = IntPtr.Zero;
          m_bInit = false;
          m_bAlreadyExist = false;
          m_rwData = IntPtr.Zero;
          m_hSharedMemoryFile = IntPtr.Zero;
      }

      ~ShareMemory()
      {
          ShareMemoryClose();
      }

      /// <summary>
      /// 创建共享内存
      /// </summary>
      /// <returns>0=创建成功;1=创建共享体失败;2=打开失败;3=印射失败; 4=共享内存命名错误</returns>
      public int CreateMemory()
      {
          if (MemSize <= 0) MemSize = 0x00800000;
          if (ShareName.Length > 0)
          {
              //创建内存共享体(INVALID_HANDLE_VALUE)
              m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)MemSize, ShareName);
              if (m_hSharedMemoryFile == IntPtr.Zero)
              {
                  m_bAlreadyExist = false;
                  m_bInit = false;
                  MemPtr = IntPtr.Zero;
                  return 1; //创建共享体失败
              }
              else
              {
                  if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建
                  {
                      m_bAlreadyExist = true;
                      CloseHandle(m_hSharedMemoryFile);
                      m_hSharedMemoryFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, ShareName);
                      if (m_hSharedMemoryFile == null)
                      {
                          MemPtr = IntPtr.Zero;
                          return 2;//打开共享内存失败
                      }
                  }
                  else                                         //新创建
                  {
                      m_bAlreadyExist = false;
                  }
              }
              //创建内存映射
              m_rwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, (uint)MemSize);
              if (m_rwData == IntPtr.Zero)
              {
                  m_bInit = false;
                  CloseHandle(m_hSharedMemoryFile);
                  MemPtr = IntPtr.Zero;
                  return 3; //创建内存映射失败
              }
              else
              {
                  m_bInit = true;
                  MemPtr = m_rwData;
              }
          }
          else
          {
              return 4; //参数错误
          }
          return 0;     //创建成功
      }

      public byte[] ReadByteFromMemory(int dataLength, int pos = -1)
      {
          if (IntPtr.Zero == MemPtr)
          {
              return new byte[0];
          }
          byte[] datas = new byte[dataLength];
          if (pos == -1)
          {
              Marshal.Copy(MemPtr, datas, 0, dataLength);
          }
          else
          {
              IntPtr offPtr = IntPtr.Add(MemPtr, pos);
              Marshal.Copy(offPtr, datas, 0, dataLength);
          }
          return datas;
      }

      /// <summary>
      /// 读取共享内存并返回到类
      /// </summary>
      /// <param name="type">读取的类型</param>
      /// <returns>读取的数据</returns>
      public Object ReadFromMemory(Type type)
      {
          if (IntPtr.Zero == MemPtr)
          {
              return null;
          }

          Object obj = Marshal.PtrToStructure(MemPtr, type);
          return obj;
      }

      /// <summary>
      /// 读取类并写入共享内存
      /// </summary>
      /// <param name="obj">需要读取的类(结构体)</param>
      /// <returns>返回0表示写入成功,返回-1表示写入失败</returns>
      public int WriteToMemory(Object obj)
      {
          if (IntPtr.Zero == MemPtr)
          {
              return -1;
          }

          Marshal.StructureToPtr(obj, MemPtr, false);

          return 0;
      }

      /// <summary>
      /// 关闭共享内存(解除印射,关闭句柄)
      /// </summary>
      public void ShareMemoryClose()
      {
          if (m_bInit)
          {
              UnmapViewOfFile(m_rwData);
              CloseHandle(m_hSharedMemoryFile);
              m_bInit = false;
          }
      }

      /// <summary>
      /// 获取共享内存印射地址
      /// </summary>
      /// <returns></returns>
      public IntPtr GetPtr()
      {
          return MemPtr;
      }

      /// <summary>
      /// 获取文件句柄
      /// </summary>
      /// <returns></returns>
      public IntPtr GetFileMapPtr()
      {
          return m_hSharedMemoryFile;
      }

      /// <summary>
      /// 获取共享内存大小
      /// </summary>
      /// <returns></returns>
      public long GetSize()
      {
          return MemSize;
      }

      /// <summary>
      /// 获取共享内存名字
      /// </summary>
      /// <returns></returns>
      public string GetName()
      {
          return ShareName;
      }
  }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1962011.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Anaconda配置记录-linux环境

Anaconda Distribution 是一个 Python/R 数据科学分发&#xff0c;其中包含&#xff1a; conda - 用于命令行界面的包和环境管理器 Anaconda Navigator - 基于 conda 构建的桌面应用程序&#xff0c;具有从托管环境中启动其他开发应用程序的选项 超过 300 个自动安装的软件包…

记录一次Dump文件分析之旅

背景 在生产环境中&#xff0c;服务运行一段时间后&#xff0c;我们遇到了JVM内存使用率超过90%的告警。考虑到我们的服务正常情况下每周都会进行重启&#xff0c;通常不应该出现如此高的内存使用率问题。 前置操作 在检查JVM相关配置时&#xff0c;我们使用Jinfo命令发现当…

Covalent 启动面向 CXT 质押者的生态伙伴空投计划

Covalent Network&#xff08;CXT&#xff09;是模块化人工智能数据基础设施&#xff0c;其宣布了合作伙伴生态系统空投计划的首个项目&#xff1a;TAIKO。此举旨在为 CXT 代币质押者提供来自其庞大生态系统的空投机会。首次空投将于 2024 年 8 月 1 日进行&#xff0c;向 CXT …

疯狂交互学习的BM3推荐算法(论文复现)

疯狂交互学习的BM3推荐算法&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 疯狂交互学习的BM3推荐算法&#xff08;论文复现&#xff09;多模态推荐系统优点 示例对比学习什么是对比学习&#xff1f;关键思想优点 自监督学习什么是自监督…

【只出现一次的数字 III】python刷题记录

R2-位运算专题. 目录 哈希表 位运算 ps: 一眼哈希表啊 哈希表 class Solution:def singleNumber(self, nums: List[int]) -> List[int]:dictdefaultdict(int)ret[]for num in nums:dict[num]1for key in dict.keys():if dict[key]1:ret.append(key)return ret怎么用位…

支持AI的好用的编辑器aieditor

一、工具概述 AiEditor 是一个面向 AI 的下一代富文本编辑器&#xff0c;她基于 Web Component&#xff0c;因此支持 Layui、Vue、React、Angular 等几乎任何前端框架。她适配了 PC Web 端和手机端&#xff0c;并提供了 亮色 和 暗色 两个主题。除此之外&#xff0c;她还提供了…

Hive3:库操作常用语句

1、创建库 create database if not exists myhive;2、选择库 use myhive;3、查看当前选择的库 SELECT current_database();4、查看库详细信息 desc database myhive;可以查看数据文件在hdfs集群中的存储位置 5、创建库时制定hdfs的存储位置 create database myhive2 …

机器学习课程学习周报六

机器学习课程学习周报六 文章目录 机器学习课程学习周报六摘要Abstract一、机器学习部分1.1 循环神经网络概述1.2 循环神经网络架构1.2.1 深层循环神经网络1.2.2 Elman网络和Jordan网络1.2.3 双向循环神经网络 1.3 长短期记忆网络1.4 LSTM原理1.5 RNN的学习方式1.6 RNN中的梯度…

基于站点的中国6小时PM2.5数据集(1960-2020)

基于站点的中国6小时PM2.5数据集&#xff08;1960-2020&#xff09; 数据介绍 几十年来&#xff0c;PM2.5改变了地球上的辐射平衡&#xff0c;增加了环境和健康风险&#xff0c;但直到2013年才在中国得到广泛监测。历史长期 PM2.5具有高时间分辨率的记录是必不可少的&#xff0…

段页式存储-系统架构师(三十七)

1、一个完整的系统需要从不同的角度进行描述&#xff0c;下图属于软件架构设计中的&#xff08;&#xff09;&#xff0c;用于&#xff08;&#xff09;视图来描述软件系统。 问题1 A对象图 B时序图 C构件图 D类图 问题2 A进程 B开发 C物理 D逻辑 解析&#xff1a; 从…

Golang | Leetcode Golang题解之第306题累加数

题目&#xff1a; 题解&#xff1a; func stringAdd(x, y string) string {res : []byte{}carry, cur : 0, 0for x ! "" || y ! "" || carry ! 0 {cur carryif x ! "" {cur int(x[len(x)-1] - 0)x x[:len(x)-1]}if y ! "" {cur i…

卷积神经网络的入门基本介绍 | 带你快速上手各种概念【附图解】

文章目录 1、简介2、核心概念3、关键操作4、常见架构5、训练过程6、重要概念图解⭐6.1、卷积神经网络工作⭐6.2、卷积核6.3、全连接与卷积网络的对比6.4、池化层6.5、感受野和卷积堆叠6.6、神经元计算和激活函数 7、卷积网络可以改进的地方8、结论 &#x1f343;作者介绍&#…

清爽简洁!这可能是开源界功能最强大的项目开发管理系统

&#x1f482; 个人网站: IT知识小屋&#x1f91f; 版权: 本文由【IT学习日记】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 文章目录 写在前面项目简介项目特点设计思想技术栈项目展示项目获取 写在前…

(免费领源码)java+SpringBoot+mysql车辆故障报修系统26719-计算机毕业设计项目选题推荐

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;车辆维修行业当然也不例外。车辆故障报修系统是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff…

SpringBoot内置Tomcat启动原理

文章目录 概要整体架构流程技术细节 概要 Springboot 内嵌 tomcat是如何启动的 &#xff1f; 整体架构流程 springboot启动 ---- autoconfiguration ---- tomcat springboot在启动后&#xff0c;通过context 确定是 org.springframework.boot.web.servlet.context.Annotatio…

微软蓝屏事件:全球网络安全与系统稳定性的警示

文章目录 每日一句正能量前言探讨软件更新流程中的风险管理和质量控制机制软件更新的风险风险管理策略质量控制措施测试流程缺陷识别实施质量控制结论 提供预防类似大规模故障的最佳方案或应急响应对策设计冗余系统实施灾难恢复计划建立高可用架构应急响应对策利用自动化工具和…

DRAM的可靠性受什么因素影响

挑战 随着IC尺寸的不断减小&#xff0c;它们变得更容易受到多种环境因素的损害&#xff0c;尤其是对于放置在高温或低温且空气中含有微粒的恶劣环境中的系统。在远程维护受限的室外偏远地区设置的系统特别容易受到攻击。 IC质量不均。晶圆内的IC可能不一定具有相同的质量。一个…

Coggle数据科学 | Kaggle赛题总结:AI数学奥赛挑战赛

本文来源公众号“Coggle数据科学”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;Kaggle赛题总结&#xff1a;AI数学奥赛挑战赛 赛题名称&#xff1a;AI Mathematical Olympiad - Progress Prize 1 赛题类型&#xff1a;大模型、…

Python开源项目月排行 2024年6月

#2024年6月2024年7月1日1wxPython一个基于C的跨平台GUI工具包wxWidgets的Python封装库。它提供了丰富的GUI组件&#xff0c;如按钮、文本框、菜单、对话框等&#xff0c;使得开发者能够轻松构建功能齐全且用户体验良好的桌面应用。wxPython的设计目标是尽可能地利用操作系统的原…

【中项】系统集成项目管理工程师-第8章 信息安全工程-8.2信息安全系统

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…