98下的进程中和系统中的某个dll只有一份.
2000下各自一份.互不想干.如何理解,或精简了的资料.

解决方案 »

  1.   

    MSDNWin32 DLL 映射到调用进程的地址空间中。默认情况下,每个使用 DLL 的进程都有自己的所有 DLL 全局变量和静态变量的实例。如果 DLL 需要与它的由其他应用程序加载的其他实例共享数据,则可使用下列方法之一: ◎使用 data_seg 杂注创建命名数据节。 
    ◎使用内存映射文件。请参阅有关内存映射文件的 Win32 文档。 
      

  2.   

    一般情况下,如果一个应用程序使用了动态链接库,Win32系统保证内存中只有DLL的一份复制品,这是通过内存映射文件实现的。DLL首先被调入Win32系统的全局堆栈,然后映射到调用这个DLL的进程地址空间。在Win32系统中,每个进程拥有自己的32位线性地址空间,如果一个DLL被多个进程调用,每个进程都会收到该DLL的一份映像。与16位Windows不同,在Win32中DLL可以看作是每个进程自己的代码。
      

  3.   

    利用共享内存DLL共享数据DLL允许进程以类似于Windows 3.1 DLL共享数据的方式访问读写数据,多个进程都可以对该共享数据DLL进行数据操作,达到共享数据的目的。在WIN32中为建立共享内存,必须执行以下步骤:
    首先创建一个有名的数据区。这在Visual C++中是使用data_seg pragma宏。使用data_seg pragma宏必须注意数据的初始化:
    #pragma data_seg("MYSEC")
    char MySharedData[4096]={0};
    #pragma data_seg()
    然后在用户的DEF文件中为有名的数据区设定共享属性。
    LIBRARY TEST
    DATA READ WRITE
    SECTIONS
        .MYSEC READ WRITE SHARED这样每个附属于DLL的进程都将接受到属于自己的数据拷贝,一个进程的数据变化并不会反映到其他进程的数据中。在DEF文件中适当地输出数据。以下的DEF文件项说明了如何以常数变量的形式输出MySharedData。
    EXPORTS
        MySharedData CONSTANT
    最后在应用程序(进程)按外部变量引用共享数据。
    extern _export"C"{char * MySharedData[];}
    进程中使用该变量应注意间接引用。
    m_pStatic=(CEdit*)GetDlgItem(IDC_SHARED);
    m_pStatic->GetLine(0,*MySharedData,80);
      

  4.   

    据我所知道的,在win9x,内存被分成两半,从 $00000000 - $7FFFFFFF 是由分给各个进程所有. 没有进程可以直接访问另一个进程所拥有的内存。除非使用特定的API,$80000000 - $FFFFFFFF 是共享区,归所有的进程共享(这应该也是win9x不稳定的原因之一),在win2000/nt没有共享区.所有的32位内存地址对每一个进程总是私有的。
    所以在win9x中改变共享区的内存,那么所有的使用共享区的进程都将直接受影响,马上可以看见效果。我觉得这是方便,也是一个缺点。所以win9x不稳定.一个不是那么完善的程序可能很偶然的使用了某个API修改了在共享区的重要资料而导致整个系统受影响。
    所以对我们来说,有好有不好,好就好在省功夫,烦就烦在稳定性是个大大大大的问题。在内存中的进程,谁知道是不是“家有恶邻”,不小心被别人挖了墙角。我想这也是win9x中有些程序想冲突情况严重的原因。这是我的理解,然而最令我不明白的是,很多文献都一再申明2000没有共享地带,然而,恰恰就是JennyVenus()所写的那一段让我迷惑。那一段代码所起的作用到底对2000的内存做过什么?有的文献说:这是把进程引进到2000的共享带。!?!?!?!?!?!?!?!?!?!为什么,我该相信谁????
      

  5.   

    我想 Win9x 和 WinNT/2000 都尽量在物理存储器上保持 dll 只有一份拷贝,然后将这一份拷贝映射到各个内存空间,这样最有效率。但是 dll 中的全局变量(一般的)必须相对独立,Win9x 的解决办法是把包含全局变量的段每个进程复制一份,共享所有代码段,而 WinNT 采用 copy-on-write 方法使对映射页面的写入不影响 dll 的全局拷贝。显然 WinNT 的方法避免了 dll 相互共享而又保证了大多数页面只有一份物理拷贝。对于指定为共享属性的段,我想只要在加载时不执行上述的保护动作就可以实现了,Win9x 将共享段视为代码段处理,WinNT 将共享段直接映射为 PAGE_READWRITE 而非 PAGE_WRITECOPY 属性。
      

  6.   

    抱歉没有说清楚,上面说的和 Win32 虚拟内存机制有关,windows 通过虚拟内存机制为每个进程模拟出一个 32bit 的“平坦”内存空间,其中每一个页面(一般是 4KB 但是一些硬件平台上可能不一样)拥有三种状态,未使用(free),保留(reserve),提交(commit), 初始状态为 free,reserve 表示页面已分配但是没有和为他分配物理存储器(内存,硬盘上的交换文件),commit 表示页面已分配并指派了物理存储器。其中只有 commit 的页面可以被访问。此外,每个页面可以拥有不同的保护属性
    Read, Write, Execute, Guard, Copy-On-Write等(参考 VirtualProtect 函数),页面和他分配的物理存储器类型和位置没有关系(实际上经常改变),不同的页面可以对应同一块物理存储器。在这个基础上,windows 实现了文件映射机制,简单的说就是把文件作为物理存储器映射到内存空间某段连续的页面上,对页面的读写操作(经过缓冲)转换为对文件的操作。同一文件的同一部分可以被多次映射到不同的进程的内存空间里,并被这些进程所共享。windows 的 exe, dll 加载机制类似于 windows 文件映射机制,加载的 dll 在物理存储器中只有一份,但是映射到不同的进程的页面上。Win9x 复制某些包含全局变量的段的页面到新的物理存储器,并修改进程中的相应页面映射到这些物理存储器上,而 WinNT 在进程试图改写某个页面时,才为页面分配新的物理存储器,复制其内容,然后更新进程中页面映射使随后的改写发生在新的物理存储器上。建立一个最简单的 Win32 dll 可以直接选菜单 File --> New --> Projects --> Win32 Dynamic-Link Library --> 填写 Project Name 然后 OK --> Step 1 of 1 --〉选 A Dll that exports some symbols然后就是一个简单的输出了一些函数和变量的 dll如果要创建共享 segment 可以这样:#pragma data_seg(".sdata")
    // 申明一些全局变量,注意一定要初始化,否则不会编译到指定的 segment 
    #pragma data_seg()#pragma comment(linker, "/SECTION:.sdata, RWS")