#pragma data_seg() 在进程通信,数据共享上的用法总结

#pragma data_seg()一般用于DLL中,用于定义一个共享的,有名字的数据段。命名的数据段中的全局变量可以被多个进程共享,否则多个进程之间无法共享DLL中的全局变量。例如:同一程序的多个实例共享一份数据,一个实例对数据的修改会影响到其他实例,具体到窗口中就是,一个实例中的数据显示变化引起其他各个实例中数据显示的更新。

具体应用实例:

a)   实现进程间的数据共享,通信

Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的;然而Win32环境中,情况发生了变化,DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。进程载入DLL时操作系统自动把DLL地址映射到进程的私有空间即进程的虚拟地址空间,同时复制该DLL的全局数据的一份拷贝到该进程空间。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的。因此Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。虽然访问同一个Dll的各进程之间共享存储器是通过存储器映射文件技术实现的,但也可以把这些需要共享的数据分离出来,放置在一个独立的数据段里,并将段的属性设置为共享

b)     一个实例启动次数,并对其进行处理比如只能启动一个实例

 

下面逐个介绍以上2种实例:

 

//————————————第一种应用————————————

 

Windows在一个Win32程序的地址空间周围筑了一道墙。通常,一个程序的地址空间中的数据是私有的,对别的程序而言是不可见的。但是执行STRPROG的多个执行实体表示了STRLIB在程序的所有执行实体之间共享数据是毫无问题的。当您在一个STRPROG窗口中增加或者删除一个字符串时,这种改变将立即反映在其它的窗口中。

在全部例程之间,STRLIB共享两个变量:一个字符数组和一个整数(记录已储存的有效字符串的个数)。STRLIB将这两个变量储存在共享的一个特殊内存区段中:

#define MAX_STRINGS 256

#define MAX_LENGTH 63

#pragma  data_seg ("shared")//建立数据段,命名为shared

//接下来初始化的变量都放入shared数据段中,需要对变量进行专门的初始化,

//否则编译器将把它们放在普通的未初始化数据段中而不是放在shared

int    iTotal = 0 ;

WCHAR  szStrings [MAX_STRINGS][MAX_LENGTH + 1] ={'\0' } ;

#pragma  data_seg ()//标识数据段结束

编译器的连结器必须知道有一个「shared」共享数据段。操作如下:
1在「Project Settings」对话框选择「Link」页面卷标。
2选中「STRLIB」时在「Project Options」字段(在ReleaseDebug设定中均可),包含下面的连结叙述:/SECTION:shared,RWS // RWS表示段具有读、写和共享属性。
或者
直接用DLL原始码指定连结选项,就像我们在STRLIB.C那样:

#pragma comment(linker,"/SECTION:shared,RWS")      

 

//——————————————第二种应用——————————————


另一个实际应用,用共享数据来统计应用程序启动的次数,并作相应的处理。

在应用程序的入口处:
//
控制应用程序只能启动一次
#pragma data_seg("flag_data")
   int count=0;
#pragma data_seg()
#pragma comment(linker,"/SECTION:flag_data,RWS")

程序中:
   if(count>1)
   {
      MessageBox("
已经启动了一个应用程序""Warning",MB_OK);
      return FLASE;

}
   count++;

 

//———————————————注意事项—————————————————


共享数据必须初始化,否则微软编译器会把没有初始化的数据放到.BSS段中,从而导致多个进程之间的共享行为失败
例如:

#pragma data_seg("MyData")
int g_Value; // Note that the global is not initialized.
#pragma data_seg()

DLL提供两个接口函数:
int GetValue()
{
     return g_Value;
}
void SetValue(int n)
{
     g_Value = n;
}

然后启动两个进程 A B A B 都调用了这个 DLL ,假如 A 调用了 SetValue(5); B 接着调用 int m = GetValue(); 那么 m 的值不一定是 5 ,而是一个未定义的值。因为 DLL 中的全局数据对于每一个调用它的进程而言,是私有的,不能共享的。假如你对 g_Value 进行了初始化,那么 g_Value 就一定会被放进 MyData 段中。换句话说,如果 A 调用了 SetValue(5); B 接着调用 int m = GetValue(); 那么 m 的值就一定是 5 !这就实现了跨进程之间的数据通信!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值