334上位机VC MFC利用内存映射进行线程通信
利用内存映射进行线程通信
功能展示
程序与程序之间时有数据通讯的需求,我们当前例程利用内存映射实现两程序的映射,即程序间的通讯,效果如图,点击按钮,可以从内存中读取事先写入的数据,内存的数据由另一程序事先写入,另一程序我们也一并打包在例程中;
要点提示
实现内存映射前,首先得利用函数CreateFileMapping()创建一内存映射对象,之后再调用函数MapViewOfFile()将内存映射对象映射到进程的地址空间当中,这样我们就可以在程序中写入与读取共享内存中的数据了;
HANDLE CreateFileMapping( HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCTSTR lpName);
参数说明:
hFileong,指定欲在其中创建映射的一个文件句柄。0xFFFFFFFF(-1,即INVALID_HANDLE_VALUE)表示在页面文件中创建一个可共享的文件映射。
lpFileMappigAttributes:SECURITY_ATTRIBUTES,它指明返回的句柄是否可以被子进程所继承,指定一个安全对象,在创建文件映射时使用。如果为NULL(用ByVal As Long传递零),表示使用默认安全对象。
flProtectong,下述常数之一:
PAGE_READONLY 以只读方式打开映射
PAGE_READWRITE 以可读、可写方式打开映射
PAGE_WRITECOPY 为写操作留下备份
可组合使用下述一个或多个常数:
SEC_COMMIT 为文件映射一个小节中的所有页分配内存
SEC_IMAGE 文件是个可执行文件
SEC_RESERVE 为没有分配实际内存的一个小节保留虚拟内存空间
dwMaximumSizeHighong,文件映射的最大长度的高32位。
ERROR_ALREADY_EXISTS,则表示内存映射对象指定名字已经存在。有关其他返回值的意义见MSDN的详细说明
dwMaximumSizeLowong,文件映射的最大长度的低32位。如这个参数和dwMaximumSizeHigh都是零,就用磁盘文件的实际长度。
lpName:String,指定文件映射对象的名字。如存在这个名字的一个映射,函数就会打开它。用vbNullString可以创建一个无名的文件映射。
调用CreateFileMapping的时候可能会出现的GetLastError的相应错误:
ERROR_FILE_INVALID 如果企图创建一个零长度的文件映射
ERROR_INVALID_HANDLE 内存空间的命名和现有的内存映射,互斥量,信号量,临界区有同名
ERROR_ALREADY_EXISTS 表示内存空间命名已经存在
LPVOID MapViewOfFile( HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, DWORD dwNumberOfBytesToMap);
参数1:hFileMappingObject 为CreateFileMapping()返回的文件映像对象句柄。
参数2:dwDesiredAccess 映射对象的文件数据的访问方式,而且同样要与CreateFileMapping()函数所设置的保护属性相匹配。 可取以下值:
FILE_MAP_ALL_ACCESS 等价于CreateFileMapping的 FILE_MAP_WRITE|FILE_MAP_READ. 文件映射对象被创建时必须指定PAGE_READWRITE 选项.
FILE_MAP_COPYA 可以读取和写入文件.写入操作会导致系统为该页面创建一份副本.在调用CreateFileMapping时必须传入PAGE_WRITECOPY保护属性.
FILE_MAP_EXECUTE 可以将文件中的数据作为代码来执行.在调用CreateFileMapping时可以传入PAGE_EXECUTE_READWRITE或PAGE_EXECUTE_READ保护属性.
FILE_MAP_READ 可以读取文件.在调用CreateFileMapping时可以传入PAGE_READONLY或PAGE_READWRITE保护属性.
FILE_MAP_WRITEA 可以读取和写入文件.在调用CreateFileMapping时必须传入PAGE_READWRITE保护属性.
参数3:dwFileOffsetHigh 表示文件映射起始偏移的高32位.
参数4:dwFileOffsetLow 表示文件映射起始偏移的低32位.(64KB对齐不是必须的)
参数5:dwNumberOfBytes 指定映射文件的字节数.
实现功能
1.新建基于对话框的应用程序,用于创建一内存映射对象,并写入共享数据
2.主对话框中添加一成员变量void* m_pViewData;并初始化
HANDLE hShareMem;
hShareMem = CreateFileMapping((HANDLE)0xffffffff,NULL,PAGE_READWRITE,0,10000,"MemFile");
m_pViewData = MapViewOfFile(hShareMem,FILE_MAP_WRITE,0,0,0);
3.添加一编辑框IDC_EDIT1及按钮控件,关联按钮的点击函数实现将编辑框的数据写入内存中
void CShareDlg::OnBwrite()
{
CString str;
GetDlgItemText(IDC_EDIT1,str);
strcpy((char*)m_pViewData,(char*)(LPCTSTR)str);
}
4.再新建一基于对话框的应用程序,用于创建一内存映射对象,并从中读取数据
5.在主对话框中添加一成员变量void* m_pViewData;并初始化
HANDLE hShareMem;
hShareMem = CreateFileMapping((HANDLE)0xffffffff,NULL,PAGE_READWRITE,0,10000,"MemFile");
m_pViewData = MapViewOfFile(hShareMem,FILE_MAP_WRITE,0,0,0);
6.然后添加一编辑框IDC_EDIT1及按钮控件,关联按钮的点击函数实现将内存数据读取显示在编辑框中
void CGkbc8Dlg::OnButton1()
{
CString str;
strcpy((char*)(LPCTSTR)str,(char*)m_pViewData);
SetDlgItemText(IDC_EDIT1,str);
}
我们来演示下功能实现的整个过程
如果您认可,可联系功能定制! 如果您着急,充值会员可直接联系发您资料!
|