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

news/2024/10/5 22:17:50/

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 filelpBase = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);#endifreturn 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 closemunmap(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 DM16hMapFile_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 DMIOstring  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 DM8string 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 DM16string 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 一定》0if (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 一定》0if (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 一定》0if (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.ppmy.cn/news/1473482.html

相关文章

深度解析Java世界中的对象镜像:浅拷贝与深拷贝的奥秘与应用

在Java编程的浩瀚宇宙中&#xff0c;对象拷贝是一项既基础又至关重要的技术。它直接关系到程序的性能、资源管理及数据安全性。然而&#xff0c;提及对象拷贝&#xff0c;不得不深入探讨其两大核心类型&#xff1a;浅拷贝&#xff08;Shallow Copy&#xff09;与深拷贝&#xf…

【网络安全】第6讲 黑客与网络攻击(笔记)

一、黑客简介 1、什么是黑客 2、黑客的产生 &#xff08;1&#xff09;任何系统都不可能绝对安全 &#xff08;2&#xff09;人类的好奇心 &#xff08;3&#xff09;经济利益驱使 黑客产业链各个角色分工明确&#xff1a;老板、病毒编写者&#xff0c;流量商&#xff0c;盗…

散度的可视化

散度的可视化 flyfish 向量场和散度 假设我们有一个简单的向量场&#xff1a; F ( x , y , z ) \mathbf{F} (x, y, z) F(x,y,z)在这里&#xff0c;向量场 F \mathbf{F} F 是由三个分量组成的向量&#xff0c;每个分量是空间坐标 x x x、 y y y、 z z z 的函数&#xff…

深度学习 - 稠密张量与稀疏张量的区别

稠密张量与稀疏张量的区别 在机器学习和数据处理领域&#xff0c;张量是处理和存储多维数据的核心结构。张量主要分为两类&#xff1a;稠密张量&#xff08;Dense Tensor&#xff09;和稀疏张量&#xff08;Sparse Tensor&#xff09;。它们在数据存储和计算效率方面有显著的区…

AI是在帮助开发者还是取代他们?

AI是在帮助开发者还是取代他们&#xff1f; 在软件开发领域&#xff0c;生成式人工智能&#xff08;AIGC&#xff09;正在改变开发者的工作方式。无论是代码生成、错误检测还是自动化测试&#xff0c;AI工具正在成为开发者的得力助手。然而&#xff0c;这也引发了对开发者职业…

自动驾驶世界模型系列 - 2 | Delphi

0. 资源链接 论文: Unleashing Generalization of End-to-End Autonomous Driving with Controllable Long Video Generation 项目: https://westlake-autolab.github.io/delphi.github.io 1. 背景动机 端到端自动驾驶技术是当前的主流&#xff0c;对训练数据的规模和质量有更…

【Unity URP】通过代码动态添加URP渲染通道RendererFeature

URP的渲染通道RendererFeature可以很方便的实现一些渲染问题,比如渲染顺序问题,遮挡后的材质替换等等。 那么我们如何通过代码来动态添加和修改呢? 首先我们需要获取到当前的URP配置文件,在对配置文件进行添加 1.通过反射获取当前UniversalRendererData 我们通过Graphic…

add_metrology_object_generic 添加测量模型对象。找两条直线,并计算两条线的夹角和两个线的总长度,转换成毫米单位

*添加测量模型对象 *将测量对象添加到测量模型中 *算子参数&#xff1a; *    MeasureHandle&#xff1a;输入测量模型的句柄&#xff1b; *    Shape&#xff1a;输入要测量对象的类型&#xff1b;默认值&#xff1a;‘circle’&#xff0c;参考值&#xff1a;‘circl…