我创建了一个共享连接的规则DLL共享数据段,其中只有一个变量。在一个程序里设置这个共享变量,还在这个程序里读取能够读到;用两个程序访问(一个程序的两份拷贝),一个设置这个共享变量,另一个读取,但读取的总为零。各种方法都试了,extern "C" __declspec(dllimport),引用lib库,动态连接,都试了,但都无法共享数据。其它方式DLL共享数据都能成功,唯独这个不成功,麻烦大家说说是怎么回事?

解决方案 »

  1.   

    网上搜的,看看你的代码对否。
    1,什么是共享数据段?为什么要用共享数据段??它有什么用途??在Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的;而在Win32环境中,情况却发 生了变化,DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。当进程在载入DLL时,操作系统自动把DLL地址映射到该进程的 私有空间,也就是进程的虚拟地址空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名 称相同,但其值却并不一定是相同的,而且是互不干涉的。因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。在访问同一个Dll的各进程之间共享存储器是通过存储器映射文件技术实现的。 也可以把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。必须给这些变量赋初值,否则编译器会把没有赋初始值的变量放 在一个叫未被初始化的数据段中。2,#pragma data_seg()一般用于DLL中。也就是说,在DLL中定义一个共享的,有名字的数据段。最关键的是:这个数据段中的全局变量可以被多个进程共享。否则多个进程之间无法共享DLL中的全局变量。3,共享数据必须初始化,否则微软编译器会把没有初始化的数据放到未初始化的数据段中,从而导致多个进程之间的共享行为失败。4,如果你在一个DLL中这么写:#pragma data_seg("shared")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,而是一个未定义的值。
    如果对g_Value进行了初始化,那么g_Value就一定会被放进 shared 段中。换句话说,如果A调用了SetValue(5); B接着调用int m = GetValue(); 那么m的值就一定是5!这就实现了跨进程之间的数据通信!5,仅定义一个数据段还不能达到共享数据的目的,还要告诉编译器该段的属性,有两种方法可以实现该目的(其效果是相同的):一种方法是在.DEF文件中加入如下语句: SETCTIONS shareddata READ WRITE SHARED另一种方法是在项目设置链接选项(Project Setting --〉Link)中加入如下语句:
    /SECTION:shareddata,rws   (字母RWS表示段具有读、写和共享属性。)
      

  2.   

    你是两个exe 访问同个dll吗?  一个exe修改了dll中的变量想另一个exe取这个值?
    没这样使用过,不敢断言是否可实现,但是不同的exe load DLL,DLL的数据都是会被初始化的,也就是说两个EXE 调用了同一个DLL,但是数据是两份不同的。
      

  3.   

    是这个意思,两个EXE访问同一个DLL。其它方式的DLL都可以这样共享数据了,只有“共享连接到MFC的规则DLL”的方式不能共享数据。是不是有什么办法使这种方式也能共享数据呢?
      

  4.   

    三楼说的是写拷贝,但是如果标明了是共享段的话,是可以被进程共享的,建议楼主参看《windows核心编程》。