为什么LoadLibrary会成功或失败,具体取决于当前目录?

时间:2014-09-17 17:35:36

标签: delphi firefox delphi-xe2 loadlibrary

我遇到了LoadLibrary的问题,这是我以前从未想过的事情,这是我第一次看到这个,我试图加载一个模块" nss3.dll"内部" C:\ Program Files(x86)\ Mozilla Firefox \"使用LoadLibrary,为了从中导入一些函数,但它失败并带有0返回值,我尝试从system32文件夹中硬编码.dll并且它工作正常,任何想法发生了什么?

编辑:我忘了提及,克服这个问题的方法是调用SetCurrentDirectory然后导入模块而不指定.dll的路径,但事实并非如此,我想找出原因它发生在我身上。

编辑:这里有一些代码片段(可行):

var
  NSSModule: HModule;
begin
  SetCurrentDir('C:\Program Files (x86)\Mozilla Firefox');
  NSSModule := LoadLibrary('nss3.dll');

这个,不起作用,不明白为什么......:

var
  NSSModule: HModule;
begin
  NSSModule := LoadLibrary('C:\Program Files (x86)\Mozilla Firefox\nss3.dll');

2 个答案:

答案 0 :(得分:8)

您正在加载的DLL正试图在同一文件夹(mozglue.dll)中静态加载另一个dll。这就是为什么当你设置工作目录时它的工作原理。如果不这样做,因为firefox的路径不在系统路径中,api无法找到dll。您可以找到有关dll搜索here的详细信息。

答案 1 :(得分:3)

对此的解释是DLL本身链接到位于同一目录中的其他DLL。如果不加载这些其他依赖项,则无法加载DLL。并且正是加载器尝试加载失败的依赖项。

此DLL的预期主机是Firefox,它也位于同一目录中。当Firefox加载DLL时,依赖关系会成功解析,因为DLL搜索路径会搜索包含可执行文件的目录。但是当您的程序尝试加载模块时,找不到相关模块,因为您的可执行文件位于不同的目录中。

您报告的错误代码为ERROR_MOD_NOT_FOUND。这是指其中一个依赖项而不是您加载的模块。事实上,这在加载程序错误中很常见。您可能会遇到难以置信的错误代码,但通常解释是它们引用了解析依赖模块的错误。

修改工作目录不是解决方案。这确实解决了您的问题,但您不应该依赖工作目录来进行依赖项解析。系统提供的影响DLL搜索的机制是SetDllDirectoryAddDllDirectory。例如:

SetDllDirectory('C:\Program Files (x86)\Mozilla Firefox');
NSSModule := LoadLibrary('nss3.dll');
SetDllDirectory(nil);

此处需要MSDN主题Dynamic-Link Library Search Order