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

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

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

  • 通过共享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 DllShare
    EXPORTS
    SetMsg
    GetMsg
    
    SEGMENTS 
    .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 here
    	if(SetMsg())
    	{
    		MessageBox("设置Msg成功!");
    	}
    
    }
    
    void CDllShareTestDlg::OnGetMsg() 
    {
    	// TODO: Add your control notification handler code here
    	char *pMsg = NULL;
    	if(GetMsg(&pMsg))
    	{
    		MessageBox(LPCTSTR(pMsg));
    	}
    }
  7. 运行结果图:【VC编程技巧】动态链接库☞1.4进程间共享数据_第1张图片

你可能感兴趣的:(编程,测试,dll,library,linker)