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

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.mfbz.cn/a/768722.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PTA-线性表实验(JAVA)

题目1&#xff1a;Josephus环的问题及算法 【实验内容】 编程实现如下功能&#xff1a; 题意说明&#xff1a;古代某法官要判决n个犯人的死刑&#xff0c;他有一条荒唐的法律&#xff0c;将犯人站成一个圆圈&#xff0c;从第start个犯人开始数起&#xff0c;每数到第distance的…

Redis基础教程(一):redis配置

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

信息安全体系架构设计

对信息系统的安全需求是任何单一安全技术都无法解决的&#xff0c;要设计一个信息安全体系架构&#xff0c;应当选择合适的安全体系结构模型。信息系统安全设计重点考虑两个方面&#xff1b;其一是系统安全保障体系&#xff1b;其二是信息安全体系架构。 1.系统安全保障体系 安…

Go语言特点、编译及命令

本文主要分为三部分内容分别为&#xff1a;Go语言的特点介绍&#xff1b;编译windows、linux环境文件及Go命令。 目录 Go语言特点 编译文件 编译window文件 编译linux文件 Go命令&#xff08;build/run/install/env&#xff09; 编译文件 直接运行程序 安装程序 配置G…

【分布式数据仓库Hive】常见问题及解决办法

目录 一、启动hive时发现log4j版本和hadoop的版本有冲突 解决办法&#xff1a;删除hive下高版本的slf4j 二、启动hive报错 Exception in thread "main" java.lang.NoSuchMethodError:com.google.common.base.Preconditions.checkArgument(ZLjava/lang/Object;)V …

个人博客|PHP源码|支持多国语言切换

一. 前言 今天小编给大家带来了一款可学习&#xff0c;可商用的&#xff0c;支持多国语言的个人博客网站源码&#xff0c;支持二开&#xff0c;无加密。此博客相当简洁&#xff0c;也适合海外。详细界面和功能见下面视频演示。 如果您正好有此需求源码&#xff0c;请联系小编…

Zabbix 配置钉钉告警

Zabbix 配置钉钉告警 随着企业IT运维需求的不断增加&#xff0c;及时、准确地获取系统告警信息显得尤为重要。在众多告警工具中&#xff0c;Zabbix 因其强大的监控功能和灵活的告警机制&#xff0c;成为了很多企业的首选。同时&#xff0c;随着企业内部沟通工具的多样化&#…

苹果AI的国产大模型之争,没有悬念

文 | 智能相对论 作者 | 陈泊丞 苹果终于公布了最新的AI进程。 一个月前&#xff0c;正如此前预期的那样&#xff0c;人工智能是今年 WWDC 发布会的焦点。全程105分钟的主题演讲&#xff0c;就有40多分钟用于介绍苹果的AI成果。 苹果似乎还有意玩了一把“谐音梗”&#xff…

海外虚拟卡开卡平台有哪些?无限开卡,无其他限制

随着时代的发展很多小伙伴都需要海外虚拟卡&#xff0c;海外虚拟卡开卡平台我这里用的是Fomepay的&#xff0c;他们比较人性化&#xff0c;有客服&#xff0c;随时可咨询 对于消费者而言&#xff0c;虚拟卡号提供了隐私&#xff0c;因此广告商更难以跟踪和定位购买行为&#x…

深入浅出:进程管理的艺术

目录 进程的定义 进程的特征 进程的状态 进程与程序的区别 进程的控制和管理 进程的特点 1. 虚拟内存空间的分配 2. 时间片轮转调度 图解&#xff1a; 进程段 数据段&#xff08;Data Segment&#xff09; 正文段&#xff08;Text Segment&#xff09; 堆栈段&…

Redis持久化详解

【关闭文件、AOF 刷盘、释放内存这三个任务都有各自的任务队列】所以不是单线程 Redis有两种持久化方案&#xff1a; RDB持久化 AOF持久化 基于Redis集群解决单机Redis存在的问题 【Redis是单进程的】 【也有人做分布式section】 【主从集群中多个从就是做负载均衡的】 …

一维信号全变分(TV)降噪方法(MATLAB)

信号降噪一直是领域研究的热点&#xff0c;这是一项十分有意义并且极具挑战性的工作&#xff0c;经过几十年来相关科研人员的共同努力&#xff0c;降噪技术得到了极大的发展&#xff0c;并在现实生活中也得到了广泛的应用。其中&#xff0c;许多常用的方法有&#xff1a;小波变…

vector模拟实现【C++】

文章目录 全部的实现代码放在了文章末尾准备工作包含头文件定义命名空间和类类的成员变量 迭代器迭代器获取函数 构造函数默认构造使用n个值构造迭代器区间构造解决迭代器区间构造和用n个值构造的冲突拷贝构造 析构函数swap【交换函数】赋值运算符重载emptysize和capacityopera…

上位机网络通讯

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 using System; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 上位机网络通讯 {public partial class Form1 : Form{public Form1(){Initializ…

BUG TypeError: GPT2Model.forward() got an unexpected keyword argument ‘past’

TypeError: GPT2Model.forward() got an unexpected keyword argument past’ 环境 transformers 4.38.1详情 这是由于新版的transformers 对GPT2Model.forward() 参数进行了改变导致的错误。具体是past名称改为了 past_key_values 。 解决方法 找到错误语…

黑马点评-Redis的缓存击穿,缓存雪崩,缓存穿透,互斥锁,逻辑过期

文章目录 1.缓存穿透2.缓存雪崩3.缓存击穿3.1 互斥锁3.2 基于逻辑过期 1.缓存穿透 解决办法 写入NULL值到Redis缓存&#xff0c;以后就会命中Redis的控制缓存而不会出现请求直接打到数据库的问题&#xff01; 代码 2.缓存雪崩 这个概念很好理解&#xff0c;雪崩就是无数的…

开发者聊科学作息时间表

非常有幸对科学作息时间表app的开发者做一次采访。 问&#xff1a;你对科学作息时间表app满意么&#xff1f; 答&#xff1a;非常不满意&#xff0c;我们的设想是让他更智能&#xff0c;更多的提醒方式&#xff0c;更好的交互体验。如果作为一个闹钟他是非常不合格的&#xff0…

视图库对接系列(GA-T 1400)三、代码生成

项目准备 我们把需要的第三方包和需要生成的库引入到对应的**基础包**中对应版本号 <properties><java.version>1.8</java.version><httpclient.version>4.5</httpclient.version><httpcore.version>4.4.12</httpcore.version><…

tinyshop项目部署

参考软件测试之测试用例设计&#xff08;四&#xff09;_管理后台 测试用例-CSDN博客 1、下载xampp 2、修改apache和mysql的端口分别为4431 &#xff0c;8013和3306 3、访问页面&#xff1a;输入ip:端口号&#xff0c;出现以下页面即成功 4、安装tinyshop商城 将解压的tinys…

Chart.js四个示例

示例代码在图片后面&#xff0c;点赞加关注&#xff0c;谢谢 条形图 雷达图 折线图 圆环图 完整例子代码 具体代码在干什么看粗体加重的注释 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <me…