C/C++ 日常学习总结(第二十二篇)共享内存实现C++
大家都知道进程之间的通信可以使用共享内存,但是在具体代码中如何实现呢?下面就介绍下操作原理和我自己的实现代码。
在linux下使用的是shmget,shmat,shmdt等函数,所以在网上看到这类的,基本就是在介绍linux环境下的实现,windows下不适用,但可以看其原理。
0.传输数据的结构定义
struct Splayer { int numid; int age; char sex; char name[128]; char ip[256]; int port; };
上面结构的定义较为简单,仅为了测试使用。
1.我们会创建两个程序,一个称之服务端,一个称之客户端。
服务端:(1.)创建共享内存区域 (2.)内存映射到当前进程 (3.)写入数据
客户端:(1.)打开共享内存区域 (2.)内存映射到当前进程 (4.)读出数据
2.服务端
void CMySharedServerDlg::MySharedMemory() { /* struct Splayer { int numid; int age; char sex; char name[128]; char ip[256]; int port; }; */ //1.创建共享内存区域 HANDLE hfile = ::CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,65536,"GameQueen"); if(NULL==hfile) { AfxMessageBox("创建失败!",MB_OK,0); return; } //2.内存映射 PVOID pview = NULL; pview = ::MapViewOfFile(hfile,FILE_MAP_ALL_ACCESS,0,0,1024); if (NULL==pview) { AfxMessageBox("映射失败!",MB_OK,0); return; } //char* pMessage = "皇后come from MySharedServerDlg!";//单独字符串也可传输 Splayer player; player.numid = 6666; player.age = 24; player.sex = "1"; strcpy(player.name,"tangwei"); strcpy(player.ip,"192.168.1.102"); player.port = 8080; DWORD dmessage = sizeof(Splayer); memcpy_s(pview,1024,&player,dmessage); }上面是源码,简诉下过程:
(1)、创建一个特定大小的文件映射对象,名称为“GameQueen”,也可以宏来定义。
(2)、将这个对象的文件视图映射到进程的地址空间,然后向视图中写入数据/字符串。
(3)、函数参数分析
// Create the file mapping object. hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // Use paging file - shared memory NULL, // Default security attributes PAGE_READWRITE, // Allow read and write access 0, // High-order DWORD of file mapping max size MAP_SIZE, // Low-order DWORD of file mapping max size FULL_MAP_NAME // Name of the file mapping object );
pView = MapViewOfFile( hMapFile, // Handle of the map object FILE_MAP_ALL_ACCESS, // Read and write access 0, // High-order DWORD of the file offset VIEW_OFFSET, // Low-order DWORD of the file offset VIEW_SIZE // The number of bytes to map to view );
3.客户端
源码:
void CMyShareClientDlg::MySharedMemory() { HANDLE hfile = OpenFileMapping(FILE_MAP_READ,FALSE,"GameQueen"); if (NULL==hfile) { AfxMessageBox("不能打开共享内存",MB_OK,0); return; } PVOID pview; pview = ::MapViewOfFile(hfile,FILE_MAP_READ,0,0,1024); if (NULL==pview) { AfxMessageBox("不能打开2",MB_OK,0); return; } //char* pStr = (char*)pview; //CString str(pStr); //OutputDebugString(str); Splayer *player = (Splayer*)pview;//上面读取字符串,此处是读取结构体信息 }
过程分析:
(1.)执行客户程序CMyShareClientDlg
(2.)打开这个名称为“GameQueen”的文件映射对象
(3.)然后把相同的文件映射视图映射到自己的地址空间中
(4.)然后从视图中读取服务进程所写入的数据。
4.截图
服务端发送数据:
客户端接收数据:
5.注意
(1.)由于事件,信号,互斥对象和文件映射等这些内核对象都共享同一个名字空间,所以如果这个名字和其他一个对象的名称重名的话那么将创建失败。
(2.)为了实现共享内存,进程应首先调用CreateFileMapping函数然后在hFile参数中传入INVALID_HANDLE_VALUE宏来替代句柄。相应的文件映射对象会从系统的分页文件中获得一段内存。如果hFile参数的值是INVALID_HANDLE_VALUE,那么你在调用CreateFileMapping时必须给共享内存指定一个大小值。
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇: C/C++ 日常学习总结(第二十三篇)父子进程间通信——环境变量
- 下一篇:没有了