2009-09-10 32 views
0

我无法获得有关从C++动态加载DLL文件的很多信息。 我知道它使用一些函数,如LoadLibrary和FreeLibrary与GetProcAddress。但是它是如何在操作系统透视图的内部实际工作的,例如它实际上查找DLL文件的位置以及它像内存一样加载的位置?有人可以用一些图帮助我吗?在操作系统中使用C++动态加载DLL的内部机制?

+1

这应该被标记为操作系统相关的问题,而不是C++之一。 – 2009-09-10 12:36:12

+0

请注意,实现细节是特定于平台的,尽管共享库的概念对大多数平台都很常见。你对Win32感兴趣吗? – 2009-09-10 12:36:21

+0

是的,这可能与操作系统有关,但很高兴知道在英国win32 C++ – ukanth 2009-09-10 12:40:01

回答

1

DLL搜索顺序上MSDN描述,并且有一个article on DLL loading,以及两部分article describing PE formatpart two here)(他们稍微老了,但我不认为他们是过时的)。浏览MSDN杂志和MSJ档案,你可能会发现更多。

+0

“关于DLL加载的文章”链接很有意思,希望对此有所了解。 – ukanth 2009-09-10 13:55:09

0

对于Win32,装载程序的细节在MSDN上。见here

从你的C++代码中,你是对的(对于Windows),你用:: LoadLibrary加载并用:: GetProcAddress解析函数指针。通常,您会将GetProcAddress的结果转换为您知道入口点函数的类型,然后在您的程序中使用它。例如,如果您有像浏览器这样的插件体系结构,您可以决定插件目录是什么,获取该目录的文件名列表,并为每个DLL调用:: LoadLibrary(筛选文件名将取决于你)。对于每一个,您都可以使用GetProcAddress来解析所需的入口点,将它们存储在该库的结构中,并将它们放入一些插件列表中。稍后,您将通过这些函数指针调用该插件来完成其工作。

如果您指定相对路径(例如“foo.dll”而不是“c:\ foo.dll”),则OS库搜索路径将启动。MSDN中的详细信息。

此外,DLL会加载到您的进程的地址空间。通常情况下,你不关心在哪里,但过去,通过“重新绑定”你的DLL可以获得更快的加载时间。我不认为OS加载程序如何将内存放置在内存中有任何保证,但您始终可以在进程的地址空间中获取基址。

您的DLL的入口点(dllmain)也可以响应各种消息 - 线程挂接,进程挂接 - 以合理的方式进行初始化。

0

有两种使用DLL的方法。您可以在运行时动态加载它,或者在链接时静态链接它。

如果使用LoadLibrary动态加载,则操作系统有some mechanism to determine where to look for DLLs。然后它尝试加载它们。然后,您可以尝试获取函数指针(通过字符串或普通函数)并调用这些函数。

如果链接是静态的,基本上链接器会为每个DLL的函数添加一个对DLL和一些跳转表的引用。当操作系统加载应用程序时,它会查找对这些DLL的引用,尝试加载这些DLL,并将加载的DLL函数的地址修补到跳转表中。只有这样,你的应用程序才会被加载并启动。

请注意,实际上这有点复杂。例如,DLL可以依次引用其他DLL。因此,当加载器加载DLL时,在可以考虑加载DLL之前,它需要(可能递归地)加载其他DLL。