动态库加载

weixin_38053515 2019-02-15 05:22:06
请问一下当一个进程加载一个DLL时,是不是把DLL中的函数拷贝到目标进程地址空间中。
...全文
46 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_38155464 2019-02-21
  • 打赏
  • 举报
回复
你好,
你还有任何问题吗? 如果您的问题已经解决,请帮助标记答案。 如果没有,请随时与我们联系。
您的理解与合作将不胜感激。
weixin_38155167 2019-02-20
  • 打赏
  • 举报
回复

你好,


根据你的描述,你所说的重定位是在一个执行文件需要载入多个DLL时,而这些DLL的内存地址存在冲突时,就需要进行的内存地址修正。而不是像上面所说的多个执行文件调用相同DLL时的情况。

同样的,重定位发生在载入DLL到当前程序的地址空间的时候,所以发生在调用LoadLibrary函数阶段。


Best wishes,

Jeanine Zhang

weixin_38141713 2019-02-20
  • 打赏
  • 举报
回复
你好:
     当DLL加载的时候不是会发生重定位吗?DLL不一定会被加载到建议的地址空间的。
weixin_38121257 2019-02-20
  • 打赏
  • 举报
回复

你好,


>>请问一下重定位发生在哪个阶段呢?


我不太明白你说的重定位是什么意思。是否指的是两个程序加载同一个DLL时,分别将DLL加载到当前程序的地址空间?如果是的话,加载DLL都是在调用LoadLibrary函数阶段。


Best wishes,

Jeanine Zhang
weixin_38109627 2019-02-20
  • 打赏
  • 举报
回复
你好:
      请问一下重定位发生在哪个阶段呢?
weixin_38093910 2019-02-19
  • 打赏
  • 举报
回复
你好:
      我想了解一下调用了LoadLibrary后,系统做了哪些事情。
weixin_38104933 2019-02-19
  • 打赏
  • 举报
回复

你好,


>>动态链接方式,数据代码是只有一份的,那重定位是修改代码中的地址的,如果有两个程序加载同一个DLL的时候,都需要重定位,那会怎么操作呢。


Win32系统会确保内存中只有一个该DLL的拷贝,这是通过内存映射文件来实现的。不同的进程分别将这份DLL的代码段地址映射到自己的进程空间中,同时不同的进程在自己的进程空间分别有各自的一份该DLL的数据段拷贝。
在Win32环境中,每个进程都有了它自己的地址空间,DLL函数中的代码所创建的任何对象(包括变量)都归调用它的进程所有。当进程在载入DLL时,操作系统自动把DLL内存地址映射到该进程的私有空间,也就是进程的虚拟地址空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间。在物理内存中,多进程载入DLL时,DLL的代码段实际上是只加载了一次,只是将物理地址映射到了各个调用它的进程的虚拟地址空间中,而全局数据会在每个进程都分别加载。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的。因此,如果不采取特别的措施,DLL中的数据段不能跨进程共享。如果将数据段的属性修改为共享的,这样该数据将被映像到所有的使用到该DLL的进程,即多个进程将共享该数据段。


希望我的回答对你有帮助,如果还有其他问题,欢迎与我们联系。


Best wishes,

Jeanine Zhang
weixin_38096686 2019-02-19
  • 打赏
  • 举报
回复
你好:
      谢谢你的解答。我还有一个问题请教一下,动态链接方式,数据代码是只有一份的,那重定位是修改代码中的地址的,如果有两个程序加载同一个DLL的时候,都需要重定位,那会怎么操作呢。
weixin_38095754 2019-02-19
  • 打赏
  • 举报
回复

你好,


>>我想了解一下调用了LoadLibrary后,系统做了哪些事情。


您所说的调用Loadlibrary之后,系统做的事情,是否是指动态加载DLL时,调用Loadlibrary之后系统做的事情?

系统做了以下事情:
1,调用了Loadlibrary之后,通过此函数加载DLL到当前进程使用的地址空间,获取模块句柄。
2,调用GetProcAddress函数动态获得DLL函数的入口地址,获取指向程序要调用的每个导出函数的指针。
3,当一个DLL通过调用Loadlibrary函数显示加载后,任何时刻都可以通过调用Freelibrary函数显示地将DLL从内存中卸载。


Best wishes,

Jeanine Zhang
weixin_38080713 2019-02-18
  • 打赏
  • 举报
回复

你好,


>>请问一下映射具体有哪些步骤?


你想问的是否是将DLL映射到当前进程使用的地址空间的具体步骤?将DLL映射到当前进程使用的地址空间是通过LoadLibrary函数完成的,这也就是LoadLibrary函数的功能。我不太明白你想知道的具体步骤是指什么?又或者你想知道的是如何动态加载DLL的步骤?这个我已经在第一条给过相关问题的答复。如果还有其他问题,欢迎与我们联系。


Best wishes,

Jeanine Zhang
weixin_38076910 2019-02-18
  • 打赏
  • 举报
回复
你好:
      请问一下映射具体有哪些步骤?
weixin_38070435 2019-02-18
  • 打赏
  • 举报
回复

你好,


>>我想了解的是DLL被映射到进程的地址空间时,操作系统做了哪些事,是怎么做映射的。


DLL在被可执行文件导入到内存中后,并不是直接被拷贝到可执行文件的进程地址空间中,而是通过内存映射将DLL映射到进程地址空间,在物理内存中只存在一份DLL 。LoadLibrary的功能就是把DLL映射到当前进程使用的地址空间。一旦载入,即可访问库内保存的资源。


Best wishes,

Jeanine Zhang
weixin_38069095 2019-02-18
  • 打赏
  • 举报
回复
你好:
      我想了解的是DLL被映射到进程的地址空间时,操作系统做了哪些事,是怎么做映射的。
weixin_38067167 2019-02-18
  • 打赏
  • 举报
回复

你好,


>>调用Loadlibrary 之后,会将DLL的内容全部加载到内存中吗?那样内存中不是有很多DLL中的内容。

LoadLibrary函数将指定的模块加载到调用过程的地址空间中。指定的模块可能会导致加载其他模块。如果函数成功, 则返回值是模块的句柄。当一个DLL文件用Loadlibrary 显示加载后,任何时刻都可以使用Freelibrary函数显示的将它从内存中卸载。


关于LoadLibrary函数的更多细节,你可以参看这个链接: https://docs.microsoft.com/zh-cn/windows/desktop/api/libloaderapi/nf-libloaderapi-loadlibrarya


Best wishes,

Jeanine Zhang
weixin_38066953 2019-02-15
  • 打赏
  • 举报
回复
你好:
      调用Loadlibrary 之后,会将DLL的内容全部加载到内存中吗?那样内存中不是有很多DLL中的内容。
weixin_38060626 2019-02-15
  • 打赏
  • 举报
回复

你好,


感谢在

433

社区成员

发帖
与我相关
我的任务
社区描述
其他技术讨论专区
其他 技术论坛(原bbs)
社区管理员
  • 其他技术讨论专区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧