载入时动态链接及运行时动态链接,译自MSDN

原创 2005年03月02日 13:22:00

载入时动态链接

 

  系统启动一个使用载入时动态链接的程序时,使用连接程序放置的到文件的信息来定位进程所需要的DLL的名称。然后系统将在以下位置顺序搜寻DLL:

  1. 应用程序载入目录
  2. 当前目录
  3. 系统目录。通过GetSystemDirectory 函数可以得到。
  4. 16位系统目录。没有函数可以获取该目录,但它是被搜索的。

    Windows Me/98/95: 目录不存在

     

  5. Windows目录。通过GetWindowsDirectory 即可得到。
  6. PATH环境变量中所列目录。

Windows Server 2003, Windows XP SP1: HKLM/System/CurrentControlSet/Control/Session Manager/SafeDllSearchMode 默认值为1 (当前目录在系统及Windows目录后进行搜索)。

Windows XP:  如果HKLM/System/CurrentControlSet/Control/Session Manager/SafeDllSearchMode 为1,当前目录在系统及Windows目录后搜索,但在PATH环境变量所列的目录前。默认值为0(当前目录在系统及Windows目录前进行搜索)。注意载入时该值会被缓存到每线程的基础部分。

  如果系统不能找到所需DLL,就会终止进程并显示一个对话框报告错误信息。否则系统把DLL映射到进程的虚地址空间并增加DLL引用计数。

  接着系统调用入口点函数,函数收到一个代码指出进程正在载入该DLL。如果入口点函数没有返回TRUE,系统将终止进程并报告错误。关于入口点函数的更多信息,请参见“动态链接库入口点函数”。

  最后,系统用导入DLL函数的启动地址修改函数地址表。

  DLL将在初始化期间映射到进程的虚地址空间,并仅在需要时载入到物理内存中。

 

运行时动态链接

 

  当应用程序调用LoadLibraryLoadLibraryEx 函数时,系统就会尝试按载入时动态链接搜寻次序(参见载入时动态链接)定位DLL。如果找到,系统就把DLL模块映射到进程的虚地址空间中,并增加引用计数。如果调用LoadLibraryLoadLibraryEx 时指定的DLL其代码已经映射到调用进程的虚地址空间,函数就会仅返回DLL的句柄并增加DLL引用计数。注意:两个具有相同文件名及扩展名但不在同一目录的DLL被认为不是同一个DLL。

  系统在调用LoadLibrary或LoadLibraryEx的线程上下文中调用入口点函数。如果已经有进程通过调用LoadLibrary或LoadLibraryEx函数载入了DLL,且没有调用FreeLibrary,那么入口点函数就不会再次调用。

  如果系统找不到DLL,又或者入口点函数返回FALSE,LoadLibrary或LoadLibraryEx将返回NULL。如果LoadLibrary或LoadLibraryEx调用成功,将返回DLL模块的句柄。进程可以通过该句柄标识调用GetProcAddress、FreeLibrary或FreeLibraryAndExitThread函数的DLL。

  GetModuleHandle返回的句柄可以被GetProcAddress、FreeLibrary或FreeLibraryAndExitThread所使用。只有当DLL通过载入时链接或前次LoadLibrary、LoadLibraryEx调用已经映射到进程的地址空间时,GetModuleHandle才会成功。GetModuleHandle 不会增加模块的引用计数。GetModuleFileName 函数通过GetModuleHandle、LoadLibrary或LoadLibraryEx返回的句柄获取所关联的模块全路径。

  模块可以通过GetModuleHandle、LoadLibrary或LoadLibraryEx返回的句柄,然后调用GetProcAddress得到DLL中出口函数的地址。

  如果不再需要一个DLL模块的话,进程可以调用FreeLibrary或FreeLibraryAndExitThread(来释放)。这些函数将减少模块的引用计数,并且如果引用计数为0时,将从进程的虚地址空间取消该DLL的映射。

  使用运行时动态链接即使DLL不可用的话,进程也能继续运行,然后进程可以通过一个变更方法达到最终目的。例如,如果进程不能找到一个DLL,它可以尝试另外一个或者向用户提示错误。如果用户可以提供丢失的DLL的全路径,进程就可以不管是否在正常的搜索路径中而使用该路径信息。然而如果是载入时链接的话,系统就会终止。

  使用运行时动态链接时,如果DLL使用DllMain函数为进程的每个线程完成初始化就会产生问题,这是因为线程在LoadLibrary或LoadLibraryEx调用前入口点函数不被调用。关于如何处理该问题的示例,可参照“动态链接库的线程局部存储”。

相关文章推荐

程序的装入和链接

程序的装入和链接 标签: phpweb服务优化extensionzendcache 2010-07-05 11:02 5787人阅读 评论(4) 收藏 举报 ...

程序的链接:静态链接,装入时链接,运行时链接

静态链接是在生成可执行程序的时候就把库中的内容加入到程序中。 载入时动态链接是在将功能模块读入内存时把动态库中调用到的相关模块的内容载入内存。 运行时动态链接是在执行程序调用到模块内容时再将动态库中...

动态链接库DLL的加载:隐式加载(载入时加载)和显式加载(运行时加载)

静态链接库在链接时,编译器会将 .obj 文件和 .LIB 文件组织成一个 .exe 文件,程序运行时,将全部数据加载到内存。 如果程序体积较大,功能较为复杂,那么加载到内存中的时间就会比较长,最...

linux 编译,链接和加载

出处:http://duanple.blog.163.com/blog/static/7097176720111141085197/ 1.   序 最近在折腾各种.so,碰...

链接与运行时动态库依赖

The -L option supplies a colon-separated library path that is to be searched at LINK TIME for librar...

DXUT11框架浅析(3)--运行时(Run-Time)动态链接D3D的DLL

DXUT11框架浅析(3)—运行时(Run-Time)动态链接D3D的DLL                用depends打开C:\Windows\System32\d3d9.dll文件,可以看到:...

android下运行时动态链接dlopen()和dlsym()的实现

在android中,就如同在Linux下一样,我们也可以在app中,运行时动态加载一些动态链接库,执行调用其中的函数等操作。实现这一切最终依靠的就是dlopen()等几个函数。关于这几个函数的原型机这...

android下运行时动态链接dlopen()和dlsym()的实现

出处:http://my.oschina.net/wolfcs/blog/144412#OSC_h2_1 android下运行时动态链接dlopen()和dlsym()的实现 ...

关于程序动态库链接和运行时搜索路径设置的个人理解

首先我们要明确一个概念,程序动态库连接时的路径和运行时路径是不同的。现代连接器在处理动态库时将链接时路径(Link-time path)和运行时路径(Run-time path)分开,用户可以通过-...
  • lfyaa
  • lfyaa
  • 2013年08月24日 11:56
  • 1033

程序编译、链接、运行时头文件或动态链接库的查找

本文转自:http://blog.csdn.net/dlutxie/article/details/6776936           当考虑怎样总结这个头文件及动态链接库的查找问题时,我想到了一个...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:载入时动态链接及运行时动态链接,译自MSDN
举报原因:
原因补充:

(最多只允许输入30个字)