首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 求教 DLL 中变量的共享范围 [已结贴,结贴人:Joephia]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • Joephia
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 揭贴率:
    发表于:2008-07-31 14:49:53 楼主
    下面是DLL 中的一段代码,不过对其中的变量使用范围甚是头疼

    可以知道的是 var1,p,str 是所有进程(前提是加载了该dll)间共享的
    var2 是所有进程中都复制了一个备份,也就是在进程内共享的

    想知道的是:
      new 分配出来的 和 GlobalAlloc分配出来的那段内存 共享范围是什么?
      那段内存是存放在DLL 的内存段还是进程的内存段中?
      怎么动态分配内存才具有 var1 的共享范围?

    C/C++ code
    #pragma data_seg(".mem") DWORD var1=1; DWORD* p=NULL; char * str=NULL; #pragma data_seg() #pragma comment(linker, "/SECTION:.mem,RWS") DWORD var2=2; BOOL fun(){ DWORD var3=var2-var1; if(!p){ p=new DWORD[10]; } if(!str){ HGLOBAL hRes=::GlobalAlloc(0,10); str=(char*)::GlobalLock(hRes); } }
    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • akirya
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 6

    发表于:2008-07-31 14:55:321楼 得分:20
      new 分配出来的 和 GlobalAlloc分配出来的那段内存 共享范围是什么?
    当前进程
      那段内存是存放在DLL 的内存段还是进程的内存段中?
    当前进程的内存段
      怎么动态分配内存才具有 var1 的共享范围?
    使用共享内存技术
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zhoujianhei
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-31 14:58:182楼 得分:30
    new 分配的内存是在DLL堆空间中。
    GlobalAlloc是在进程堆空间中。

    怎么动态分配内存才具有 var1 的共享范围?
    使用内存映射文件。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • akirya
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 6

    发表于:2008-07-31 14:58:513楼 得分:0
    sorry有点失误
    var1,p,str 是所有进程都能取到的,
    但很明显p和str所指向的内容是当前进程的。不是所有进程都拥有的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • air_snake
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-31 15:07:434楼 得分:0
    引用 3 楼 akirya 的回复:
    sorry有点失误
    var1,p,str 是所有进程都能取到的,
    但很明显p和str所指向的内容是当前进程的。不是所有进程都拥有的

    厉害的啊,学习的了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • Joephia
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-31 15:11:385楼 得分:0
    引用 2 楼 zhoujianhei 的回复:
    new 分配的内存是在DLL堆空间中。
    GlobalAlloc是在进程堆空间中。

    怎么动态分配内存才具有 var1 的共享范围?
    使用内存映射文件。


    如果new 分配出来的是在 DLL 堆空间 中的内存,是否意味着

    在任意进程中访问p时都会指向这段地址?

    系统在映射DLL内存时是做的怎样的转换? 跟 reg,near,far 有什么关系没?

    或者只是简单的修改段址呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • liyinlei
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-31 15:18:436楼 得分:20
    new 分配出来的 和 GlobalAlloc分配出来的那段内存 共享范围是什么?
        整个进程共享。new分配在dll的运行时堆里,GlobalAlloc分配在进程默认堆里。释放的时候注意了,new的需要在dll内释放。

    那段内存是存放在DLL 的内存段还是进程的内存段中?
        当前进程

    怎么动态分配内存才具有 var1 的共享范围?
        内存映射文件
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • liyinlei
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-31 15:22:497楼 得分:0
    如果new 分配出来的是在 DLL 堆空间 中的内存,是否意味着
    在任意进程中访问p时都会指向这段地址?

    每个加载dll的进程都各自分配了,并非都指向一个地址。

    系统在映射DLL内存时是做的怎样的转换? 跟 reg,near,far 有什么关系没?
    或者只是简单的修改段址呢?
    在32位系统下,没有所谓的near,far
    一个应用程序加载dll的时候,将dll映射到自己进程空间的一段内存中。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cnzdgs
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 5

      2

      13

    发表于:2008-07-31 15:36:068楼 得分:20
    “new 分配出来的 和 GlobalAlloc分配出来的那段内存 共享范围是什么? ”
    new是在当前进程中分配内存的;GlobalAlloc是分配全局内存,其它进程也可以访问。
    “那段内存是存放在DLL 的内存段还是进程的内存段中? ”
    动态分配的内存都是在堆中分配的。
    “怎么动态分配内存才具有 var1 的共享范围? ”
    GlobalAlloc或者CreateFileMapping等方法。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • Joephia
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-31 17:27:089楼 得分:0
    引用 8 楼 cnzdgs 的回复:
    “new 分配出来的 和 GlobalAlloc分配出来的那段内存 共享范围是什么? ”
    new是在当前进程中分配内存的;GlobalAlloc是分配全局内存,其它进程也可以访问。
    “那段内存是存放在DLL 的内存段还是进程的内存段中? ”
    动态分配的内存都是在堆中分配的。
    “怎么动态分配内存才具有 var1 的共享范围? ”
    GlobalAlloc或者CreateFileMapping等方法。


    测试了下

    发现 进程间共享的变量地址开头是10即 0x10XXXXXX
    而内存分配的都是00开头  即 0x00XXXXXX

    所以GlobalAlloc 并不具有进程间共享的范围
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • Joephia
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-31 17:30:1810楼 得分:0
    按照 MSDN 的说法(找的很辛苦啊)

    Dynamic Memory Allocation
    When a DLL allocates memory using any of the memory allocation functions (GlobalAlloc, LocalAlloc, HeapAlloc, and VirtualAlloc), the memory is allocated in the virtual address space of the calling process and is accessible only to the threads of that process.

    A DLL can use file mapping to allocate memory that can be shared among processes. For a general discussion of how to use file mapping to create named shared memory, see File Mapping. For an example that uses the DllMain function to set up shared memory using file mapping, see Using Shared Memory in a Dynamic-Link Library.

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • gaoteng1984
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-31 18:36:5511楼 得分:0
    楼主十万个为什么,求知欲望值得学习~
    帮顶~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zengwenfu
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-31 18:46:5712楼 得分:5
    DLL通过文件映射将DLL映射到需要的应用程序里 ,为了防止其中一个进程修改DLL中的变量而影响到其他所有的应用程序,所有DLL里的数据都具有COPY-WRITE保护属性,就是说一个应用程序修改DLL中变量的值会先拷贝到进程自己的空间,修改的只不过拷贝的数据而已.要实现DLL进程间共享可以通过共享数据段或者共享内存等方式.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • gaoteng1984
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-31 19:01:0813楼 得分:5
    是这样的,在DLL中new出来的内存,在DLL的CRT堆里,因此可以被加载该DLL的EXE所访问。
    但是由于在多个进程加载该DLL时,该DLL可能被映射到不同的地址空间,因此new返回的指针只能在其中1个进程里有效
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • gaoteng1984
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-31 21:15:4514楼 得分:0
    Sorry啊,我刚才做了个实验,我的解答是错误的。
    new出来的内存只能被当前进程访问,其他进程该指针处的内存与其无关。
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved