#pragma data_seg一般用在dll中,dll的地址空间可以被多个进程同时映射,当进程加载时候把dll的地址空间映射到该进程的私有虚拟空间中,当所有的数据段只是用来读的时候,这些数据在内存中时一份,win2000以后采用的COW,即copy on write,在写数据时候,这份数据会被复制成单独的一份。这样在dll中时无法共享数据的,要想共享数据,就需要使用#pragma data_dataseg 来定义一个共享的数据段

1.#pragma data_seg介绍
         用#pragma data_seg建立一个有名字的数据段并定义共享数据,其具体格式为:

  #pragma data_seg ("shared")       //给共享段起的名字不能超过8个字符,否则会被截断

  HWND sharedwnd=NULL;//共享数据 ,再这个段之间的数据都可以被所有加载这个dll的进程共享

  #pragma data_seg()   
#pragma comment(linker,"/SECTION:shared,RWS")    //告诉链接器,shared段是可读可写并且是共享的 

最关键的是:这个数据段中的全局变量可以被多个进程共享。否则多个进程之间无法共享DLL中的全局变量。


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

3.你所谓的结果正确是一种错觉。如果你在一个DLL中这么写:

#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!这就实现了跨进程之间的数据通信!

可以用这种放来保证当前系统中某应用程序只被启动一次。