【文档说明】编程中的进程管理课件.ppt,共(67)页,490.699 KB,由小橙橙上传
转载请保留链接:https://www.ichengzhen.cn/view-45396.html
以下为本文档部分文字说明:
For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻Windows系统编程实用教程授课教师:职务:For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻第7章进程编程课程描述大多
数应用程序都以进程的形式运行,有时还需要在应用程序里运行或结束其他进程。本章将介绍Windows进程编程的方法。For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻本章知
识点7.1进程编程基础7.2基本进程编程7.3进程间通信For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻7.1进程编程基础7.1.1什么是进程7.1.2进程的状态For:fenlei.wdsxx.com分类信息From:news.wdsxx.
com新闻7.1.1什么是进程进程是正在运行的程序的实例。每个运行的VisualC++项目都对应一个进程,每个进程至少包含一个线程,它从main()函数开始执行,直到执行return语句返回,主线程结束,该
进程也被从内存中卸载。进程由如下几个部分组成。与程序相关联的可执行代码的映像;内存空间(通常是虚拟内存中的一些区域),其中保存可执行代码、进程的特定数据、用于记录活动例程和其他事件的调用栈、用于保存实时
产生的中间计算结果的堆(heap)。分配给进程的资源的操作系统描述符(比如文件句柄)以及其他数据资源。安全属性,比如进程的所有者和权限。处理器的状态,比如寄存器的内容、物理内存地址等。For:fenlei.wdsxx.com分类
信息From:news.wdsxx.com新闻7.1.2进程的状态For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻7.2基本进程编程7.2.1创建进程7.2.2枚举系统进程7.2.3终
止进程For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻7.2.1创建进程在应用程序中可以调用CreateProcess()函数创建一个新进程、运行其他程序,函数原型如下:BOOLWINAPICre
ateProcess(__inLPCTSTRlpApplicationName,__in_outLPTSTRlpCommandLine,__inLPSECURITY_ATTRIBUTESlpProcessAttributes,__inLPSECURITY_ATTRIBUTESlpThreadAtt
ributes,__inBOOLbInheritHandles,__inDWORDdwCreationFlags,__inLPVOIDlpEnvironment,__inLPCTSTRlpCurrentDirectory,__inLPSTARTUPINF
OlpStartupInfo,__outLPPROCESS_INFORMATIONlpProcessInformation);For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻参数说明lpApplicationName,要执行的应用程序名,可
以包括结对路径和文件名,通常可以为NULL。lpCommandLine,要执行的命令行。lpProcessAttributes,新进程的安全描述符。lpThreadAttributes,指定主线程的安全描述符。
如果为NULL,则使用默认的安全描述符。bInheritHandles,指示新进程是否从调用进程处继承句柄。dwCreationFlags,指定附加的、用来控制优先类和进程创建的标志。lpEnvironment,指向
新进程的环境块。如果为NULL,则使用调用CreateProcess()函数的进程的环境。For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻【例7.1】调用Creat
eProcess()函数运行Windows计算器程序,并显示新进程的ID号,及其主线程的Id号,代码如下:#include"stdafx.h"#include<windows.h>int_tmain(intargc,_TCHA
R*argv[]){charszCommandLine[]="calc.exe";STARTUPINFOsi={sizeof(si)};PROCESS_INFORMATIONpi;si.dwFlags=STARTF_USESHOWWINDOW;//指定wShowWindow成
员有效si.wShowWindow=TRUE;//显示新建进程的主窗口For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻接上BOOLbRet=CreateProcess(NULL,//不在此指定可执行文件的文件名szCommandLine,//命令行参数N
ULL,//默认进程安全性NULL,//默认进程安全性FALSE,//指定当前进程内句柄不可以被子进程继承CREATE_NEW_CONSOLE,//为新进程创建一个新的控制台窗口NULL,//使用本进程的环境变量NULL,//使用本进程的驱动器和目录&si
,&pi);if(bRet){//关掉不使用的句柄CloseHandle(pi.hThread);CloseHandle(pi.hProcess);printf("新进程的ID号:%d\n",pi.dwProcessId);printf("新进程的主线程ID号:%d\n",pi.dwThre
adId);}system("pause");return0;}For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻【例7.1】的运行结果For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻ShellExecute(
)函数HINSTANCEShellExecute(HWNDhwnd,//指定显示用户界面和错误信息的窗口句柄LPCTSTRlpOperation,//对指定文件要执行的操作LPCTSTRlpFile,//要执行操作的文件或对象LPCTSTRlpParameters,//指定传送给应用程序
的参数LPCTSTRlpDirectory,//指定执行操作的工作目录INTnShowCmd//指定应用程序如何显示。SW_HIDE表示隐藏窗口,SW_MAXIMIZE表示最大化窗口,SW_MINIMIZE表示最小化窗口,SW_SHOW表示在当前位置上以当前大小显示窗口,等等);F
or:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻pOperation参数的取值取值说明edit打开一个文档文件进行编辑。如果参数lpFile指定的不是一个文档文件,则操作失败explore打开资源管理器查看指定文件所在
的目录find从参数lpDirectory指定的目录开始搜索open打开指定的对象print打印指定的对象。如果参数lpFile指定的不是一个文档文件,则操作失败NULL执行默认的操作,通常执行open操作For:
fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻【例7.2】【例7.2】调用ShellExecute()函数访问google网站,代码如下:#include"stdafx.h"#include"windows.h”int_tmain(intargc,_TCHAR*
argv[]){ShellExecute(NULL,"open","http://www.google.com","","",SW_SHOW);return0;}For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻7.2.2枚举系统进
程1.使用EnumProcesses()函数2.使用进程快照For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻1.使用EnumProcesses()函数BOOLWINAPIEnumProcesses(__o
utDWORD*pProcessIds,//用于接收进程标示符列表的数组__inDWORDcb,//数组pProcessIds的大小,单位是字节__outDWORD*pBytesReturned//数组pProcessIds中返回数据的大小,单位是字节);如果函数执行
成功,则返回一个非0值;否则返回0。For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻【例7.3】调用EnumProcess()函数枚举当前Windows运行进
程的标示符(PID),代码如下:#include"stdafx.h"#include<windows.h>#include<Psapi.h>#pragmacomment(lib,"Psapi.lib"
)int_tmain(intargc,_TCHAR*argv[]){//用于接收返回的进程ID信息的数组DWORDdwProcs[1024*2];DWORDdwNeeded;//返回进程数组的大小//枚举所有进程ID。For:fen
lei.wdsxx.com分类信息From:news.wdsxx.com新闻接上if(!EnumProcesses(dwProcs,sizeof(dwProcs),&dwNeeded)){//输出出错信息。prin
tf("EnumProcessesfailed(%d).\n",GetLastError());}else{DWORDdwProcCount=dwNeeded/sizeof(DWORD);for(inti=0;i<dwProcC
ount;i++){printf("PID:%d\n",dwProcs[i]);}}system("pause");return0;}For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻【例7.3】的运行结
果For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻2.使用进程快照HANDLEWINAPICreateToolhelp32Snapshot(DWORDdwFlags,//指定快照中包含的对象
DWORDth32ProcessID//指定获取进程快照的PID。如果为0,则获取当前系统进程列表);如果函数执行成功,则返回进程快照的句柄;否则返回INVALID_HANDLE_VALUE。For:fenlei.wdsxx.com分类信息From:n
ews.wdsxx.com新闻Process32First()函数调用Process32First()函数可以从进程快照中获取第1个进程的信息,函数原型如下:BOOLWINAPIProcess32First(HANDLEhSnaps
hot,//之前调用createtoolhelp32napshot()函数得到的进程快照句柄LPPROCESSENTRY32lppe//包含进程信息的结构体);For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻结构体LPPROCESSENTRY
32LANA_ENUM结构体中包含当前逻辑网络适配器的数量。当一个物理网络适配器绑定到一个网络协议时,就对应一个逻辑网络适配器。执行NCB命令NCBENUM可以向LANA_ENUM结构体中填充逻辑网络适配器的个数和逻辑网络适配器编号,此时NCB结构体中的n
cb_buffer成员变量指向LANA_ENUM结构体。LANA_ENUM结构体的定义代码如下:typedefstruct_LANA_ENUM{UCHARlength;UCHARlana[MAX_LANA];}LANA_ENUM,*PLANA_ENUM;参数说明如下:length,系
统中包含的逻辑网络适配器数量。lana[MAX_LANA],系统中包含的逻辑网络适配器编号数组。For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻Process32Next()函数调用Process32Next()函数可以从进程快照中获取下一个进程的
信息,函数原型如下:BOOLWINAPIProcess32Next(HANDLEhSnapshot,、//之前调用createtoolhelp32napshot()函数得到的进程快照句柄LPPROCESSENTRY32lppe//包含进程信息的结构体);如果函数执
行成功,则返回TRUE;否则返回FALSE。For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻【例7.4】利用进程快照枚举当前Windows运行进程的信息,代码如下:#include"stdafx.h"#include"windo
ws.h"#include"tlhelp32.h"int_tmain(intargc,_TCHAR*argv[]){PROCESSENTRY32pe;//设置结构体pe的大小pe.dwSize=sizeof(pe);//获取系统内进程的快照HA
NDLEhProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);if(hProcessSnap==INVALID_HANDLE_VALUE){printf("CreateToolhel
p32Snapshoterror.\n");return-1;}For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻接上//遍历进程快照,显示每个进程的信息BOOLbMore=::Process32Fi
rst(hProcessSnap,&pe);while(bMore){printf("===============\n");printf("ProcessName:%s\n",pe.szExeFile);p
rintf("PID:%u\n",pe.th32ProcessID);printf("NumberofThread:%u\n",pe.cntThreads);printf("=============
==\n");bMore=::Process32Next(hProcessSnap,&pe);}//释放snapshot对象::CloseHandle(hProcessSnap);system("pause");return0;}F
or:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻4.ASTAT结构体ASTAT结构体用于描述网络适配器的状态和名字信息,定义代码如下:typedefstruct{ADAPTER_STATUSadap
t;NAME_BUFFERNameBuff[30];}ASTAT;参数adapt表示网络适配器的状态信息,参数NameBuff表示网络适配器中保存的本地网络名字信息。For:fenlei.wdsxx.com分类信息From:news.wdsxx.com
新闻【例7.4】的运行结果For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻7.2.3终止进程进程从主函数的第一行代码开始执行,直到主函数结束时终止;也可以强制结束一个进程。当进程被终止时
,系统会进行下面的操作:进程中的所有线程都被标记为“终止”状态;分配给进程的所有资源都会被释放掉;所有与该进程相关的内核对象都会被关闭;从内存中移除该进程的代码;系统设置进程的退出代码;将该进程对象设置为“受信”(Sigaled)状态。For:fenlei.wdsxx.c
om分类信息From:news.wdsxx.com新闻GetExitCodeProcess()函数调用GetExitCodeProcess()函数可以获取进程的终止状态,函数原型如下:BOOLWINAPIGetExitCo
deProcess(__inHANDLEhProcess,//进程句柄__outLPDWORDlpExitCode//用于接收进程的终止状态);如果函数执行成功,则返回TRUE;否则返回FALSE。当进程在运行中时,其终止状态为STILL_ACTI
VE。当进程被终止时,其终止状态变成退出代码。For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻ExitProcess()函数在进程中调用ExitProcess()函数
终止其自身中所有的线程,函数原型如下:VOIDWINAPIExitProcess(__inUINTuExitCode//退出代码);For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻Termin
ateProcess()函数调用TerminateProcess()函数可以终止指定的进程,函数原型如下:BOOLWINAPITerminateProcess(__inHANDLEhProcess,//要终止的进程句柄__inUINTuExit
Code//退出代码);For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻7.3进程间通信7.3.1通过自定义消息进行通信7.3.2通过管道进行通信7.3.3使用互斥体7.3.4通过共享内存进行通信For:fenlei.wdsxx.com分类信息From
:news.wdsxx.com新闻7.3.1通过自定义消息进行通信1.定义自定义消息的代码2.发送消息3.消息处理函数For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻1.
定义自定义消息的代码为了唯一标识自定义消息,需要为其定义一个消息代码。自定义的消息代码都比WM_USER要大,因为0~WM_USER-1是保留给系统消息使用。可以使用下面的代码定义一个自定义消息WM_MY_MESSAGE:#defineWM_MY_MESS
AGE(WM_USER+100)For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻2.发送消息调用PostMessage()函数将消息放置到与创建指定窗口的进程相关联的消息队列中,函数不需要等待接收方接受和处理消息就直接返
回。函数原型如下:BOOLPostMessage(HWNDhWnd,//接收消息的窗口句柄,使用HWND_BROADCAST表示所有顶层窗口UINTMsg,//发送消息的代码WPARAMwParam,//指定消息的附加信息LPARAMlParam//指定消息的附加信息);For:fe
nlei.wdsxx.com分类信息From:news.wdsxx.com新闻FindWindow()函数HWNDFindWindow(LPCTSTRlpClassName,//窗口类名,通常为NULLLPCTSTRlpWindowName//要
查找窗口的标题);For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻3.消息处理函数在接收端需要设计一个消息处理函数,它的格式如下:LRESULTOnMyMsg(WPARAMwParam,LPARAM
lParam){//处理代码……return0;}参数wParam和lParam用于接收PostMessage()函数发送消息时指定的参数。For:fenlei.wdsxx.com分类信息From:news.wdsxx
.com新闻将消息与其处理函数映射起来定义消息处理函数后还要将消息与其处理函数映射起来。在每个MFC对话框对应的.cpp文件中,都在BEGIN_MESSAGE_MAP宏和END_MESSAGE_MAP()宏之间定义消息与其处理函数映射的,例如:BEGIN_ME
SSAGE_MAP(CReceiverDlg,CDialog)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()//}}AFX_MSG_MAPEND_MESSAGE_MAP()For:fenlei.wdsxx.com分类信息Fro
m:news.wdsxx.com新闻BEGIN_MESSAGE_MAP宏BEGIN_MESSAGE_MAP宏用于标识消息映射的开始,其原型如下:BEGIN_MESSAGE_MAP(theClass,baseClass)参数theClass指定消息映射所属的类,通常是窗口类;参数ba
seClass指定参数theClass的基类。在BEGIN_MESSAGE_MAP宏和END_MESSAGE_MAP()宏之间添加一条ON_MESSAGE宏用于定义自定义消息及其处理函数的映射。ON_MESS
AGE宏的原型如下:ON_MESSAGE(message,memberFxn)参数message用于指定自定义消息的代码,参数memberFxn指定消息处理函数。For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻【
例7.5】设计一个利用自定义消息实现进程间通信的例子。1.设计发送端项目2.设计接收端项目For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻1.设计发送端项目创建一个基于对话框的MFC应用程序S
ender,定义自定义消息WM_MY_MESSAGE,代码如下:#defineWM_MY_MESSAGE(WM_USER+999)For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻单击“发送消息”按钮的代码voidCS
enderDlg::OnBnClickedButtonSendmsg(){HWNDhWnd=::FindWindow(NULL,"Receiver");::PostMessage(hWnd,WM_MY_ME
SSAGE,(WPARAM)999,NULL);}For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻2.设计接收端项目创建一个基于对话框的MFC应用程序Receiver,定义自定义消息WM_MY_MESSAGE,代码如下:#defineWM_MY_MES
SAGE(WM_USER+999)}编写消息处理函数OnMyMsg(),代码如下:LRESULTCReceiverDlg::OnMyMsg(WPARAMwParam,LPARAMlParam){charmsg[
100];sprintf(msg,"%d",(int)wParam);MessageBox(msg,"收到消息");return0;}For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻添加自定义消息及
其处理函数的映射BEGIN_MESSAGE_MAP(CReceiverDlg,CDialog)……ON_MESSAGE(WM_MY_MESSAGE,OnMyMsg)//映射消息和处理函数//}}AFX_MSG_MAPEND_MESSAGE_MAP()For:fenlei.wdsxx.co
m分类信息From:news.wdsxx.com新闻7.3.2通过管道进行通信管道(Pipe)是由标准输入输出流构成的进程链。一个进程的输出直接作为下一个进程的输入。每个连接都是一个匿名管道。管道包含一个写句柄和一个读句柄。一个进程使用写句柄向管道里写入数据,另一个进程使用读句柄从管
道中读取数据。调用CreatePipe()函数可以创建管道,函数原型如下:BOOLWINAPICreatePipe(__outPHANDLEhReadPipe,//管道的读句柄__outPHANDLEhWritePip
e,__inLPSECURITY_ATTRIBUTESlpPipeAttributes,__inDWORDnSize);For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻【例7.6】设计一个利用管道实现进程间通信的例子。主进程S
erver的代码如下:#include"stdafx.h"#include<windows.h>int_tmain(intargc,_TCHAR*argv[]){HANDLEhRead;//管道读句柄HANDLEhWrite;//管道写句柄SECURITY_ATTRIBUTESsa;//设置管道属
性sa.nLength=sizeof(SECURITY_ATTRIBUTES);sa.lpSecurityDescriptor=NULL;sa.bInheritHandle=TRUE;//指定管道句柄可以被子进程继承BOOLbRet=CreatePipe(&hRead,&hWrite,&s
a,0);//创建匿名管道if(bRet==TRUE)printf("成功创建匿名管道!\n");elseprintf("创建匿名管道失败,错误代码:%d\n",GetLastError());For:fenlei.wdsxx.com分类信息
From:news.wdsxx.com新闻接上//得到本进程的当前标准输出,以备将来恢复HANDLEhTemp=GetStdHandle(STD_OUTPUT_HANDLE);//设置标准输出到匿名管道SetStdHandle(STD_OUTPUT_HANDLE,hWrite
);STARTUPINFOsi;GetStartupInfo(&si);//获取本进程的STARTUPINFO结构信息,包括标准设备的句柄PROCESS_INFORMATIONpi;//创建客户端子进程Client.exe,它会继承父进程的标准输出,因此Client.ex
e的标准输出是到hWrite管道的bRet=CreateProcess(NULL,"Client.exe",NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi);SetStdHandle(STD_OUTPUT_HAND
LE,hTemp);//恢复本进程的标准输出if(bRet==TRUE)//输入信息printf("成功创建子进程!\n");elseprintf("创建子进程失败,错误代码:%d\n",GetLastError());For:fenlei.wdsxx.com分类信息From:news.wd
sxx.com新闻接上//读管道直至管道关闭charReadBuf[100];DWORDReadNum;//循环从管道中读取数据while(ReadFile(hRead,ReadBuf,100,&ReadNum,NULL)){ReadBuf[Re
adNum]='\0';printf("从管道读取%d字节数据:【%s】\n",ReadNum,ReadBuf);}if(GetLastError()==ERROR_BROKEN_PIPE)//输出信息printf("管道被子进程关闭\n");elseprintf(
"读数据错误,错误代码:%d\n",GetLastError());return0;}For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻子进程Client的代码#include"stdafx.h"#include<windows.
h>#include<iostream>usingnamespacestd;int_tmain(intargc,_TCHAR*argv[]){for(inti=0;i<10;i++)//发送一些数据到标准输出和标准错误{printf
("i=%d;",i);//打印提示cout<<"标准输出:"<<i<<endl;//打印到标准输出cerr<<"标准错误:"<<i<<endl;//打印到标准错误}return0;}For:fenlei.wdsx
x.com分类信息From:news.wdsxx.com新闻【例7.6】的运行结果For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻7.3.3使用互斥体HANDLEWINAPICreateMutex(__inLPSECURITY_ATTRIBUTESl
pMutexAttributes,//互斥体对象的安全属性,如果为NULLZ,则互斥体对象不能被子进程继承__inBOOLbInitialOwner,//初始化互斥对象的所有者__inLPCTSTRlp
Name//指定互斥对象的名字);如果在不同进程间使用互斥体,则该互斥体对象是全局的。全局互斥体对象的名字必须以“Global\”为前缀,而本地互斥体对象的名字则以“Local\”为前缀。For:fenlei.wdsxx.com分
类信息From:news.wdsxx.com新闻【例7.7】设计一个利用互斥体防止运行一个应用程序的多个实例的例子Mutex,代码如下:int_tmain(intargc,_TCHAR*argv[]){CreateMutex(NULL,TRUE
,"Global\\MyMutex001");if(GetLastError()==ERROR_ALREADY_EXISTS){printf("应用程序已经运行!\n");exit(0);}printf("已进入应用程序.....\n");system("pause")
;return0;}For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻第1次运行Mutex.exe的结果For:fenlei.wdsxx.com分类信息From:news.wdsxx.co
m新闻7.3.4通过共享内存进行通信每个Windows进程都有其私有的内存空间。任何进程都不能修改其他进程的内存空间,包括变量和对象等。但是多个进程间可以通过一块共享内存进行通信。共享内存是允许多个进程同时访问的内存,不同的进程可以通过共享内存进行通讯,也可
以避免在不同的程序中保存多余的数据备份。通常可以使用内存映射文件实现共享内存,用内存映射文件是由一个文件到一块内存的映射。内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的内存区域,同时将物理存储器提交给此区域,内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而
且在对该文件进行操作之前必须首先对文件进行映射。使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行过多的I/O操作,因此,内存映射文件在处理大数据量的文件时能起到相当重要的作用。For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻CreateFile
Mapping()函数HANDLECreateFileMapping(HANDLEhFile,LPSECURITY_ATTRIBUTESlpFileMappingAttributes,DWORDflProtect,DWORDdwMaximumSizeH
igh,DWORDdwMaximumSizeLow,LPCTSTRlpName);For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻参数说明hFile:创建映射对象的文件
句柄,如果使用INVALID_HANDLE_VALUE,则在物理内存中创建映射对象。lpFileMappingAttributes:被忽略,必须为NULL。flProtect,文件视图的保护方式。dwM
aximumSizeHigh,指定文件映射对象最大大小的高32位。dwMaximumSizeLow,指定文件映射对象最大大小的低32位。lpName,映射对象的名字,如果是全局映射对象,则名字可以以“Global\\”前缀开始。For:fenlei.wdsxx
.com分类信息From:news.wdsxx.com新闻MapViewOfFile()函数调用MapViewOfFile()函数可以将指定的文件视图映射到调用进程的地址空间,函数原型如下:LPVOIDMapViewOfFile(HANDLEhFileMappingObject
,//文件映射对象的句柄,通常由CreateFileMapping()函数返回DWORDdwDesiredAccess,//对文件视图的访问类型DWORDdwFileOffsetHigh,//指定开始映射的文件偏移量的高32位DWORDdwFileOffsetLow
,//指定开始映射的文件偏移量的低32位DWORDdwNumberOfBytesToMap//指定文件映射的字节数。如果为0,则映射整个文件。);For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻OpenFileMapping()函数HANDLEWINAP
IOpenFileMapping(__inDWORDdwDesiredAccess,//访问权限__inBOOLbInheritHandle,//指定子进程是否可以继承句柄__inLPCTSTRlpName//指定要打开指
定的文件映射对象的名字);如果函数执行成功,则返回打开指定的文件映射对象句柄;否则返回NULL。可以调用GetLastError()函数获取错误代码。For:fenlei.wdsxx.com分类信息F
rom:news.wdsxx.com新闻UnmapViewOfFile()函数调用UnmapViewOfFile()函数可以从调用进程的地址空间中解除文件视图的映射。函数原型如下:BOOLUnmapViewOfFile(LPCVOIDlpBaseAddress//要解除的文件视图
映射的基地址);For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻【例7.8】计一个创建文件映射对象,并向映射视图中写入数据的例子Process1,代码如下:#incl
ude"stdafx.h"#include<windows.h>#include<stdio.h>#include<conio.h>#defineBUF_SIZE256//共享内存的大小TCHARszName[]=TEXT("Global\\MyFileMappingObject");//文
件映射对象的名字TCHARszMsg[]=TEXT("Messagefromprocess1");//向共享内存中写入的数据int_tmain(intargc,_TCHAR*argv[]){HANDLEhMapFile;LPCTSTRpBuf;For:f
enlei.wdsxx.com分类信息From:news.wdsxx.com新闻接上//创建文件映射对象hMapFile=CreateFileMapping(INVALID_HANDLE_VALUE,//使用页文件NULL,PAGE_READWRITE,//可读
写0,BUF_SIZE,//文件映射对象的大小szName);//文件映射对象的名字if(hMapFile==NULL){printf("Couldnotcreatefilemappingobject(%d).\n",GetLastError());return1;}For:fenl
ei.wdsxx.com分类信息From:news.wdsxx.com新闻接上//将指定的文件视图映射到调用进程的地址空间,得到的pBuf地址就是共享内存的开始地址,共享内存的大小为BUF_SIZEpBuf=(LPTSTR)MapVie
wOfFile(hMapFile,//映射对象的句柄FILE_MAP_ALL_ACCESS,//可读写0,0,BUF_SIZE);if(pBuf==NULL){printf("Couldnotmapviewoffile(%d).\n",GetLastE
rror());return2;}//向共享内存中写入数据CopyMemory((PVOID)pBuf,szMsg,strlen(szMsg));system("pause");//等待其他进程从共享内存中读
取数据//从调用进程的地址空间中解除文件视图的映射UnmapViewOfFile(pBuf);//关闭映射对象的句柄CloseHandle(hMapFile);For:fenlei.wdsxx.com分类信息From:news.wdsxx
.com新闻设计一个从Process1创建的映射视图中读取数据的例子Process2#include"stdafx.h"#include<windows.h>#include<stdio.h>#include<conio.h>#defineBUF_SIZ
E256//共享内存的大小TCHARszName[]=TEXT("Global\\MyFileMappingObject");//文件映射对象的名字int_tmain(intargc,_TCHAR*argv[]){HANDLEhMapFile;LPCTSTRpBuf;//打开例.8中创建的
文件映射对象hMapFile=OpenFileMapping(FILE_MAP_ALL_ACCESS,//可读写FALSE,//指定子进程不继承句柄szName);//指定要打开指定的文件映射对象的名字For:fenlei.wdsxx
.com分类信息From:news.wdsxx.com新闻接上if(hMapFile==NULL){printf("Couldnotopenfilemappingobject(%d).\n",GetLastError());system("pause");return1;
}//将指定的文件视图映射到调用进程的地址空间,得到的pBuf地址就是共享内存的开始地址,共享内存的大小为BUF_SIZEpBuf=(LPTSTR)MapViewOfFile(hMapFile,//映射对象的句柄FILE_MAP_AL
L_ACCESS,//可读写0,0,BUF_SIZE);For:fenlei.wdsxx.com分类信息From:news.wdsxx.com新闻接上if(pBuf==NULL){printf("Couldnotmapviewoffile(%d).\n",Get
LastError());system("pause");return2;}//打印共享内存中的数据printf("ReadfromMapfile:%s\n\n",pBuf);//从调用进程的地址空间中解除文件
视图的映射UnmapViewOfFile(pBuf);//关闭映射对象的句柄CloseHandle(hMapFile);system("pause");return0;}For:fenlei.wdsxx.com分类信息From:news.wdsxx.co
m新闻Process2的运行结果