2.3.2 主程序和外部IO交互 (文件映射方式)----IO Client实现

news2024/11/19 6:32:05

2.3.2 主程序和外部IO交互 (文件映射方式)----IO Client C++实现

和IOServer主要差别:
1 使用Open_Client 连接
2 一定要先打开IOServer,再打开IO_Client

效果显示

在这里插入图片描述

1 C++ 代码实现

1.1 shareddataClient.h 头文件中引用

和shareddataServer.h 一样需要引入相应的头文件

 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
 #define WIN32_LEAN_AND_MEAN             //  从 Windows 头文件中排除极少使用的信息
	#include <windows.h>
#elif defined(linux) || defined(__linux)
	#include <string.h>
	#include <sys/mman.h>
	#include <fcntl.h>
	#include <unistd.h> 
#endif 
1.2 shareddataClient.h 主要调用接口
1.2.1 预定义变量名称,为了能够Linux|Windows下通用
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)   

#elif defined(linux) || defined(__linux)
   typedef void *HANDLE;
   typedef void *LPVOID;
   typedef long long __int64;
    typedef __int64 LONG_PTR, *PLONG_PTR;
     typedef unsigned long long ULONG_PTR;
    typedef unsigned long long  *PULONG_PTR; 
    typedef int BOOL; 
   #define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
#endif
1.2.2 函数接口定义
namespace SHAREDDATA
{
	typedef unsigned char uchar;
 

BD_API  int  GetIOData(uchar* p_IOData, int start, int len);
BD_API  int  SetIOData(uchar* p_IOData, int start, int len);
BD_API  int  SetDM8(uchar* p_DM8, int start, int len);
BD_API  int  GetDM8(uchar* p_DM8, int start, int len);
BD_API  int  GetDM16(uchar* p_DM16, int start, int len);
BD_API  int  SetDM16(uchar* p_DM16, int start, int len); 


/**
 * ***********************************************************************************************
 * @brief ReleaseMMF
 * 销毁资源
 * 
 * @return BD_API 
 * ***********************************************************************************************
 */
BD_API void ReleaseMMF();
/**
 * ***********************************************************************************************
 * @brief 
 * 
 * 
 * @return BD_API 
 * ***********************************************************************************************
 */
BD_API int Open_Client();
1.3 shareddataClient.cpp 函数接口实现

namespace SHAREDDATA
{ 
    #pragma region MMF 内存共享 IO 区
    // 创建共享文件句柄 
    HANDLE hMapFile_IO = INVALID_HANDLE_VALUE;
     // 文档句柄
    int  fd_io=-1;
    #pragma endregion MMF 内存IO 区
    #pragma region MMF 内存共享 DM8 区
    // 创建共享文件句柄 
    HANDLE hMapFile_DM8 = INVALID_HANDLE_VALUE;
    // 文档句柄
    int  fd_dm8=-1;
    #pragma endregion MMF 内存DM8 区
    #pragma region MMF 内存共享 DM16 区
    // 创建共享文件句柄 
    HANDLE hMapFile_DM16 = INVALID_HANDLE_VALUE;
   // 文档句柄
    int  fd_dm16=-1;
    #pragma endregion MMF 内存DM16 区
}
/**
 * SHAREDDATA 
 * 文件共享方式进行通讯
 */
namespace SHAREDDATA
{ 
  LPVOID  MapViewofFile_New(HANDLE handle,const int& fd, const int& size) 
  {
    LPVOID lpBase=nullptr;
    if(handle==nullptr||size==0)return lpBase;
    #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)   

			// 映射缓存区视图 , 得到指向共享内存的指针
			  lpBase = MapViewOfFile(
				handle,            // 共享内存的句柄
				FILE_MAP_ALL_ACCESS, // 可读写许可
				0,
				0,
				size
			);
     #elif defined(linux) || defined(__linux)
        if(fd<0)return nullptr;
        	// map memory to file
     	lpBase = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
     #endif
     return lpBase;
  }
  void  UnMapViewofFile_New(HANDLE handle,const int& size)
  {
   if(handle==nullptr||size==0)return ;
    #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)   

		 	// 解除文件映射
			UnmapViewOfFile(handle);
     #elif defined(linux) || defined(__linux)
        	// unmap and close
	    munmap(handle, size);
     #endif    
     return;
  }
/**
 * ***********************************************************************************************
 * @brief 
 * Create_Server
 * 创建一个server
 * 
 * @return BD_API 
 * ***********************************************************************************************
 */
  BD_API int  Open_Client()
{
	int nRet = 0; 
	try
	{ 	
        #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
        hMapFile_IO = OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL, "ShareMemoryIO");
		if (hMapFile_IO != INVALID_HANDLE_VALUE && hMapFile_IO>0)nRet = 0;
		else return  -1;
     
		// &1 DM8
			//&1 DM8 
	   hMapFile_DM8 =  OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL, "ShareMemoryDM8");
	   if (hMapFile_DM8 != INVALID_HANDLE_VALUE && hMapFile_DM8 > 0)nRet = 0;
	   else return -1;

		// &2 DM16
		  hMapFile_DM16 = OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL, "ShareMemoryDM16");
	   if (hMapFile_DM16 != INVALID_HANDLE_VALUE && hMapFile_DM16 > 0)nRet = 0;
	   else return -1;
 
 #elif defined(linux) || defined(__linux)
        // specify shared file path
	 // 路径一定要存在,否则会报警
       // &0 DMIO
	 string  shared_file_io = path+"ShareMemoryIO";
     fd_io = open(shared_file_io.c_str(), O_CREAT | O_RDWR | O_TRUNC, 00777);
	 if (fd_io < 0)
		{cout << "create file error" << endl;return -1; 
        }
        ftruncate(fd_io, n_max_IO_uchars); // extend file size
    
    // &0 DM8
	 string shared_file_dm8 = path+"ShareMemoryDM8";
     fd_dm8 = open(shared_file_dm8.c_str(), O_CREAT | O_RDWR | O_TRUNC, 00777);
	 if (fd_dm8 < 0)
		{cout << "create file error" << endl;return -1;
        }
         ftruncate(fd_dm8, n_max_DM8s); // extend file size
     // map memory to file
	//hMapFile_DM8 = mmap(NULL, n_max_DM8s,    , PROT_READ | PROT_WRITE, MAP_SHARED, fd_dm8, 0);
      // &0 DM16
	 string shared_file_dm16= path+"ShareMemoryDM16";
     fd_dm16 = open(shared_file_dm8.c_str(), O_CREAT | O_RDWR | O_TRUNC, 00777);
	 if (fd_dm16 < 0)
		{cout << "create file error" << endl;return -1;
        }
     ftruncate(fd_dm16, n_max_DM16s); // extend file size     
 #endif
	}
	catch (exception& e)
	{
		nRet = -1;
	}
	return nRet;
}
#pragma region  销毁共享文件 句柄
// 销毁内存 MMF 句柄
BD_API void ReleaseMMF()
{
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)  
	if (hMapFile_IO != NULL)CloseHandle(hMapFile_IO);
	if (hMapFile_DM8 != NULL)CloseHandle(hMapFile_DM8);
	if (hMapFile_DM16 != NULL)CloseHandle(hMapFile_DM16); 
#elif defined(linux) || defined(__linux)

    if(fd_io>=0)close(fd_io);
    if(fd_dm8>=0)close(fd_dm8);
    if(fd_dm16>=0)close(fd_dm16);   
#endif
}
#pragma endregion 
}
namespace SHAREDDATA
{ 
#pragma  region   MappingMemoryFile 共享
   
   /**
    * ***********************************************************************************************
    * @brief GetIOData
    *  获取IO 输出
    * @param[in] p_IOData  Comment
    * @param[in] start  Comment
    * @param[in] len  Comment
    * 
    * @return BD_API 
    * ***********************************************************************************************
    */
    BD_API  int  GetIOData(uchar* p_IOData, int start, int len)
    {
        int nRet = 0;
        std::lock_guard<std::mutex> lock(_mutex);
        try
        {
            if (len + start > n_max_IO_uchars)
            {
                len = n_max_IO_uchars - start;
            }
            if (len > 0)
            { 
                
                LPVOID lpBase = MapViewofFile_New(hMapFile_IO,fd_io, n_max_IO_uchars);
                // copy 内存
                memcpy(p_IOData, (uchar*)lpBase, len);
                //memcpy(p_IOData, b_IO, len); 
                // 解除文件映射 
                UnMapViewofFile_New(lpBase, n_max_IO_uchars);
            }
            else nRet = -1;
        }
        catch (exception& e)
        {
            nRet = -1;
        }
        return nRet;
   }

    /**
     * ***********************************************************************************************
     * @brief SetIOData
     * 设置IO数据
     * @param[in] p_IOData  Comment
     * @param[in] start  Comment
     * @param[in] len  Comment
     * 
     * @return BD_API 
     * ***********************************************************************************************
     */
    BD_API  int  SetIOData(uchar* p_IOData, int start, int len)
    {
        int nRet = 0;
        std::lock_guard<std::mutex> lock(_mutex);
        try
        {
            if (len + start > n_max_IO_uchars)
            {
                len = n_max_IO_uchars - start;
            }
            //  len 一定》0
            if (len > 0)
            {
            
                // 映射缓存区视图 , 得到指向共享内存的指针
                LPVOID lpBase = MapViewofFile_New(hMapFile_IO,fd_io,  n_max_IO_uchars); 
                // copy 内存
                memcpy((uchar*)lpBase, p_IOData, len);
                //memcpy(b_IO, p_IOData, len);
                // 解除文件映射  
                UnMapViewofFile_New(lpBase, n_max_IO_uchars);
            }
            else nRet = -1;
        }
        catch (exception& e)
        {
            nRet = -1;
        }
        return nRet;
    }
    /// @brief SetDM8
    /// @param p_DM8 
    /// @param start 
    /// @param len 
    /// @return 
    BD_API  int  SetDM8(uchar* p_DM8, int start, int len)
    {
        int nRet = 0;
        std::lock_guard<std::mutex> lock(_mutex);
        try
        {
            if (start > n_max_DM8s)
            {
                len = 0;
                nRet = -1;
                return nRet;
            }
            if (len + start > n_max_DM8s)
            {
                len = n_max_DM8s - start;
            }
            //  len 一定》0
            if (len > 0)
            {           
                // 映射缓存区视图 , 得到指向共享内存的指针
                LPVOID lpBase = MapViewofFile_New(hMapFile_DM8,fd_dm8,  n_max_DM8s);  

                memcpy((uchar*)lpBase + start, p_DM8, len);
                //memcpy(DM_8 + start, p_DM8, len);
                // 解除文件映射  
                UnMapViewofFile_New(lpBase, n_max_DM8s);
            }
            else nRet = -1;
        }
        catch (exception& e)
        {
            nRet = -1;
        }
        return nRet;
    }
    BD_API  int  GetDM8(uchar* p_DM8, int start, int len)
    {
        int nRet = 0;
        std::lock_guard<std::mutex> lock(_mutex);
        try
        {
            if (start > n_max_DM8s)
            {
                nRet = -1;
                return nRet;
            }
            if (len + start > n_max_DM8s)
            {
                len = n_max_DM8s - start;
            }
            //  len 一定》0
            if (len > 0)
            {
                if (hMapFile_DM8 == INVALID_HANDLE_VALUE)return -2;
                // 映射缓存区视图 , 得到指向共享内存的指针
                LPVOID lpBase = MapViewofFile_New(hMapFile_DM8,fd_dm8,  n_max_DM8s);  
                
                // copy 内存
                memcpy(p_DM8, (uchar*)lpBase + start, len);
                //memcpy(p_DM8, DM_8 + start, len);
                // 解除文件映射
                UnMapViewofFile_New(lpBase, n_max_DM8s);
                
            }
            else nRet = -1;
        }
        catch (exception& e)
        {
            nRet = -1;
        }
        return nRet;
    }
    BD_API  int  GetDM16(uchar* p_DM16, int start, int len)
    {
        int nRet = 0;
        std::lock_guard<std::mutex> lock(_mutex);
        try
        {
            if (start * 2 > n_max_DM16s)
            {

                nRet = -1;
                return nRet;
            }
            if (len + start > n_max_DM16s)
            {
                len = n_max_DM16s - start;
            }
            //  len 一定》0
            // 这里的 DM16 的地址   可能直接就是 int 类型的, 无需start *2 
            if (len > 0)
            {
                
                // 映射缓存区视图 , 得到指向共享内存的指针
                LPVOID lpBase = MapViewofFile_New(hMapFile_DM16,fd_dm16,  n_max_DM8s);   
                // copy 内存
                memcpy(p_DM16, (uchar*)lpBase + start, len*2);
                //memcpy(p_DM16, DM_16 + start, len * 2);
                // 解除文件映射
                UnMapViewofFile_New(lpBase, n_max_DM16s);
            }
            else nRet = -1;
        }
        catch (exception& e)
        {
            nRet = -1;
        }
        return nRet;
    }
    BD_API  int  SetDM16(uchar* p_DM16, int start, int len)
    {
        int nRet = 0;
        std::lock_guard<std::mutex> lock(_mutex);
        try
        {
            if (start * 2 > n_max_DM16s)
            {
                len = 0;
                nRet = -1;
                return nRet;
            }
            if (len + start > n_max_DM16s)
            {
                len = n_max_DM16s - start;
            }
            //  len 一定》0
            // 这里的 DM16 的地址   可能直接就是 int 类型的, 无需start *2 
            if (len > 0)
            { 
                // 映射缓存区视图 , 得到指向共享内存的指针
                LPVOID lpBase = MapViewofFile_New(hMapFile_DM16,fd_dm16,  n_max_DM8s);   
            
                // copy 内存

                memcpy((uchar*)lpBase + start, p_DM16, len*2);
                //memcpy(DM_16 + start, p_DM16, len * 2);

                // 解除文件映射
                UnMapViewofFile_New(lpBase, n_max_DM16s);
            }
            else nRet = -1;
        }
        catch (exception& e)
        {
            nRet = -1;
        }
        return nRet;
    }
#pragma endregion
}

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

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

相关文章

0 TMS320F28379D 开坑

开坑原因 最近开始做实验&#xff0c;实验室的主控采用的是F2812FPGA&#xff0c;属于够用但不好用的状态。FPGA用于生成调制信号&#xff0c;DSP完成采样和控制。师兄师姐研究拓扑及调制策略&#xff0c;对驱动数量以及驱动逻辑有比较高的要求&#xff0c;因此不好脱离FPGA&a…

机器学习原理之 -- 支持向量机分类:由来及原理详解

支持向量机&#xff08;Support Vector Machine, SVM&#xff09;是统计学习理论的一个重要成果&#xff0c;广泛应用于分类和回归问题。SVM以其高效的分类性能和良好的泛化能力在机器学习领域中占据重要地位。本文将详细介绍支持向量机的由来、基本原理、构建过程及其优缺点。…

【Excel操作】Python Pandas判断Excel单元格中数值是否为空

判断Excel单元格中数值是为空&#xff0c;主要有下面两种方法&#xff1a; 1. pandas.isnull 2. pandas.isna判断Excel不为空&#xff0c;也有下面两种方法&#xff1a; 1. pandas.notna 2. pandas.notnull假设有这样一张Excel的表格 我们来识别出为空的单元格 import panda…

基于Hadoop平台的电信客服数据的处理与分析①项目准备阶段---项目技术预研(技术架构)

任务描述 掌握项目的总体功能&#xff0c;及实现流程。预习项目中所使用到的技术和知识点。 任务指导 一、项目效果展示 二、项目架构 1、总体架构&#xff1a; 2、技术架构 技术清单&#xff1a; 功能 组件 说明 消息中间件Kafka消息队列数据采集Flume日志采集工具存储…

js获取当前浏览器地址,ip,端口号等等

前言&#xff1a; js获取当前浏览器地址&#xff0c;ip&#xff0c;端口号等等 window.location属性查询 具体属性&#xff1a; 1、获取他的ip地址 window.location.hostname 2、获取他的端口号 window.location.port 3、获取他的全路径 window.location.origin 4、获取…

机器学习 C++ 的opencv实现SVM图像二分类的测试 (三)【附源码】

机器学习 C 的opencv实现SVM图像二分类的测试 (三) 数据集合下载地址&#xff1a;https://download.csdn.net/download/hgaohr1021/89506900 根据上节得到的svm.xml&#xff0c;测试结果为&#xff1a; #include <stdio.h> #include <time.h> #include <o…

25.labview数据采集中的读取和写入文本文件和Excel表格文件

①本文将会讲解labview读取和写入文本文件和Excel文件的几种不同方式&#xff0c;讲解程序的基本原理&#xff0c;并提出具体的实施方案&#xff0c;本文内容如下所示。 ②本文文章结束会提供大家 文本和表格读取写入的源程序 &#xff0c;以便于大家学习和使用。 本文中可能用…

商城小程序论文(设计)开题报告

一、课题的背景和意义 近些年来&#xff0c;随着移动互联网巅峰时期的来临&#xff0c;互联网产业逐渐趋于“小、轻、微”的方向发展&#xff0c;符合轻应用时代特点的各类技术受到了不同领域的广泛关注。在诸多产品中&#xff0c;被誉为“运行着程序的网站”之名的微信小程序…

HUAWEI MPLS 静态配置和动态LDP配置

MPLS(Multi-Protocol Label Switching&#xff0c;多协议标签交换技术)技术的出现&#xff0c;极大地推动了互联网的发展和应用。例如&#xff1a;利用MPLS技术&#xff0c;可以有效而灵活地部署VPN(Virtual Private Network&#xff0c;虚拟专用网)&#xff0c;TE(Traffic Eng…

昇思第7天

模型训练 模型训练一般分为四个步骤&#xff1a; 构建数据集。 定义神经网络模型。 定义超参、损失函数及优化器。 输入数据集进行训练与评估。 数据集加载 import mindspore from mindspore import nn # 从 MindSpore 数据集包中导入 vision 和 transforms 模块。 # visio…

肝癌-图像分类数据集

肝癌-图像分类数据集 数据集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/18r-JS1FIv6BiyvlqDpUE0w?pwdrw5w 提取码&#xff1a;rw5w 数据集信息介绍&#xff1a; 文件夹 恶性 中的图片数量: 1008 文件夹 良性 中的图片数量: 882 所有子文件夹中的图片总数量: 1…

微软账户和本地账户有什么区别?如何切换登录账户?

Windows 操作系统是目前世界上比较流行的操作系统之一&#xff0c;在使用 Windows 系统的时候都需要我们进行登录&#xff0c;其中我们可以使用微软账户或者本地账户进行登录&#xff0c;那本地账户和微软账户有什么区别&#xff1f;下面就带大家了解一下微软账户和本地账户。 …

请不要在 Vue 中滥用“watch”功能,拜托了!

随着 Vue 3 的 Composition API 风格的普及&#xff0c;使用 watch 的成本越来越低。 现在&#xff0c;我们可以在任何地方使用 watch 来监听响应式数据。随着业务的推进&#xff0c;你可能会在代码中看到大量的 watch。 当你接手修改这些充满 watch 代码时&#xff0c;我相信…

电梯修理升级,安装【电梯节能】能量回馈设备

电梯修理升级&#xff0c;安装【电梯节能】能量回馈设备 1、节能率评估 15%—45% 2、降低机房环境温度&#xff0c;改善电梯控制系统的运行环境&#xff1b; 3、延长电梯使用寿命&#xff1b; 4、机房可以不需要使用空调等散热设备的耗电&#xff0c;间接节省电能。 欢迎私询哦…

使用PID算法实现DAC模拟量输出的快速调节

目录 概述 1 系统框架和算法 1.1 框架结构介绍 1.2 PID算法实现 1.2.1 理论介绍 1.2.2 离散化位置式PID 1.2.3 位置式PID算法 2 STM32Cube 配置项目 2.1 配置参数 2.2 GENERATE项目 3 功能实现 3.1 ADC采样数据功能 3.2 DAC数据转换 3.3 PID相关的调制函数 4 …

黄子韬vs徐艺洋卫生间风波

【热搜爆点】黄子韬VS徐艺洋&#xff1a;卫生间风波背后的职场与友情界限探讨在这个充满欢笑与意外的综艺时代&#xff0c;《跟我出游吧》再次以它独有的魅力&#xff0c;引爆了一个既尴尬又引人深思的话题——“黄子韬要上徐艺洋的卫生间&#xff1f;”这不仅仅是一句简单的调…

CSS|03 尺寸样式属性文本与字体属性

尺寸样式属性 height:元素高度height的值&#xff1a;auto 自动length 使用px定义高度% 基于包含它的块级对象的百分比高度 width&#xff1a;元素的宽度width的值与height一样span标签可以设置宽度、高度吗&#xff1f; 答&#xff1a;不可以&#xff0c;因为span标签是一个行…

mysql-sql-第十四周

学习目标&#xff1a; sql 学习内容&#xff1a; 40.查询学过「哈哈」老师授课的同学的信息 Select * from students left join score on students.stunmscore.stunm where counm (select counm from teacher left join course on teacher.teanmcourse.teanm where teache…

DCU整体硬件架构

DCU整体硬件架构 DCU整体硬件架构 首先&#xff0c;DCU通过PCI-E总线与CPU处理器相连&#xff0c;它是CPU主机系统的一个硬件扩展&#xff0c;其存在的目的是为了对程序某些模块或者函数进行加速。虽然DCU是原硬件系统的一个扩展&#xff0c;接受CPU调度指挥&#xff0c;但是在…

西部智慧健身小程序+华为运动健康服务

1、 应用介绍 西部智慧健身小程序为用户提供一站式全流程科学健身综合服务。用户通过登录微信小程序&#xff0c;可享用健康筛查、运动风险评估、体质检测评估、运动处方推送、个人运动数据监控与评估等公益服务。 2、 体验介绍西部智慧健身小程序华为运动健康服务核心体验如…