【VC编程技巧】动态链接库☞1.4进程间共享数据

来源:互联网 发布:淘宝金牌卖家 编辑:程序博客网 时间:2024/06/05 14:16

(文章转载请说明出处和作者)

常用进程间共享数据方法:

  • 通过共享DLL
  • 通过内存映射文件
  • 向另一进程发送WM_COPYDATA消息

今天主要介绍“通过共享DLL”来达到进程间共享数据,其他两种方式留在其他章节讲解。在Win32环境下,当进程启动时操作系统会为该进程分配4GB的虚拟内存,然后分析进程模块,为模块所需要的DLL创建虚拟内存,最后将DLL虚拟内存(含有代码页和数据页)中的代码页和数据页映射到进程地址空间。当另一进程也要加载此DLL时,系统不需要为DLL重新创建虚拟内存只需将DLL虚拟内存中的代码页和数据页也映射到该进程,这样也节省了内存。当进程修改DLL中的数据时,操作系统会进行写入时拷贝(该进程得到DLL的数据是拷贝后修改的数据),另一个进程访问时还是DLL中原来的数据,这是win2000系统对DLL中可写入数据的保护。那么我们要在进程间共享数据可以通过命令[#prama data_seg()创建共享节来完成。


关于节创建的格式:

#pragma data_seg(".MySec")//MySec节的名字(不超过8个字符)char g_pMsg[6] = {0};//节中的数据#pragma data_seg()#pragma comment(linker,"/section:.MySec,rws")//设置节的属性

其中最后一句设置节属性:
#pragma comment(linker,"/section:.MySec,rws")
的另一种形式是在模块文件(.DEF)中加入:
SEGMENTS .MySec    READ WRITE  SHARED


节中数据注意点:

  • 必须初始化
  • 节中数据的多少直接影响DLL的大小(节中数据不宜过多)
  • 不要存放进程相关信息(Win32种这些数据只在特定环境下有效)
  • 不要存放地址(同一地址在不同进程中的情况是不一致的,会有不可预知的错误)


实例代码:

下面我来创建一个带有共享节的DLL来演示一下进程间通信:

  1. 创建Win32DLL,工程名:DllShare
  2. DllShare.cpp代码如下
    // DllShare.cpp : Defines the entry point for the DLL application.//#include "stdafx.h"#include <stdlib.h>#pragma data_seg(".MySec")char g_pMsg[6] = {0};#pragma data_seg()//#pragma comment(linker,"/section:.MySec,rws")//设置节属性放在了模块文件中BOOL APIENTRY DllMain( HANDLE hModule,                        DWORD  ul_reason_for_call,                        LPVOID lpReserved ){    return TRUE;}BOOL __stdcall SetMsg(){strcpy(g_pMsg, "Hello");return TRUE;}BOOL __stdcall GetMsg(char **pMsg){*pMsg = g_pMsg; return TRUE;}
  3. DllShare.def代码如下:
    LIBRARY DllShareEXPORTSSetMsgGetMsgSEGMENTS .MySec    READ WRITE  SHARED
  4. 编译生成动态库DllShare.dll
  5. 创建对话框测试程序:DllShareTest
  6. 关键代码如下:
    __declspec(dllimport) BOOL __stdcall SetMsg();__declspec(dllimport) BOOL __stdcall GetMsg(char **pMsg);void CDllShareTestDlg::OnSetMsg() {// TODO: Add your control notification handler code hereif(SetMsg()){MessageBox("设置Msg成功!");}}void CDllShareTestDlg::OnGetMsg() {// TODO: Add your control notification handler code herechar *pMsg = NULL;if(GetMsg(&pMsg)){MessageBox(LPCTSTR(pMsg));}}
  7. 运行结果图:

原创粉丝点击