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 一样需要引入相应的头文件

c++ 复制代码
 #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下通用
cpp 复制代码
#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 函数接口定义
cpp 复制代码
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 函数接口实现
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
}
相关推荐
专注成就自我8 分钟前
vue+openlayers之几何图形交互绘制基础与实践
前端·vue.js·交互
奔跑的蜗牛..3 小时前
Odoo 16 中的酒店管理应用程序
交互·odoo
子衿JDD7 小时前
【论文阅读】-- TimeNotes:时间序列数据的有效图表可视化和交互技术研究
论文阅读·交互
AI 研究所1 天前
讯飞星火V4.0 发布,全面对标GPT-4 Turbo
人工智能·语言模型·机器人·交互·语音
V言微语2 天前
2.2.4 C#中显示控件BDPictureBox 的实现----ROI交互
开发语言·c#·交互
2401_857636393 天前
连接智慧未来:ChatGPT与IoT设备的交互探索
物联网·chatgpt·交互
maonianlove3 天前
QWebChannel实现与JS的交互
java·javascript·qt·交互
ly14356786193 天前
38、shell之免交互
microsoft·交互·shell