Delphi 为什么LoadLibrary成功或失败取决于当前目录?

Delphi 为什么LoadLibrary成功或失败取决于当前目录?,delphi,firefox,delphi-xe2,loadlibrary,Delphi,Firefox,Delphi Xe2,Loadlibrary,我遇到了LoadLibrary的问题,这是我第一次看到这个问题,我试图用LoadLibrary加载“C:\Program Files(x86)\Mozilla Firefox\”中的模块“nss3.dll”,以便从中导入一些函数,但返回值为0时失败,我试着从system32文件夹中硬编码一个.dll,效果很好,知道发生了什么吗 编辑:我忘了提到,解决这个问题的一种方法是调用SetCurrentDirectory,然后导入模块,而不指定.dll的路径,但事实并非如此,我想知道为什么会发生这种情况

我遇到了LoadLibrary的问题,这是我第一次看到这个问题,我试图用LoadLibrary加载“C:\Program Files(x86)\Mozilla Firefox\”中的模块“nss3.dll”,以便从中导入一些函数,但返回值为0时失败,我试着从system32文件夹中硬编码一个.dll,效果很好,知道发生了什么吗

编辑:我忘了提到,解决这个问题的一种方法是调用SetCurrentDirectory,然后导入模块,而不指定.dll的路径,但事实并非如此,我想知道为什么会发生这种情况

编辑:以下是一些片段(这很有效):

这不起作用,不知道为什么…:

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

正在加载的dll正在尝试静态加载同一文件夹(mozglue.dll)中的另一个dll。这就是为什么当您设置工作目录时它会工作的原因。否则,由于firefox的路径不在系统路径中,api将无法找到dll。您可以找到有关dll搜索的详细信息。

您正在加载的dll正在尝试静态加载同一文件夹(mozglue.dll)中的另一个dll。这就是为什么当您设置工作目录时它会工作的原因。否则,由于firefox的路径不在系统路径中,api将无法找到dll。您可以找到有关dll搜索的详细信息。

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

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

您报告的错误代码是
error\u MOD\u NOT\u FOUND
。这是指其中一个依赖项,而不是所加载的模块。事实上,这是常见的加载器错误。您可能会遇到难以置信的错误代码,但通常的解释是,它们指的是解决依赖模块的错误

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

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

此处需要阅读MSDN主题

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

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

您报告的错误代码是
error\u MOD\u NOT\u FOUND
。这是指其中一个依赖项,而不是所加载的模块。事实上,这是常见的加载器错误。您可能会遇到难以置信的错误代码,但通常的解释是,它们指的是解决依赖模块的错误

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

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

此处需要阅读MSDN主题

我们无法调试您未显示的代码。如果您需要帮助找出代码不起作用的原因,请发布代码。在此之前,您可以阅读MSDN上的文档,特别是有关如何定位库的部分。您的应用程序是32位还是64位?您无法将32位DLL加载到64位进程中(反之亦然)。@SertacAkyuz GetLastError返回126(找不到模块),有趣的是.DLL就在那里。@jlahd我的应用程序是32位运行在64位Windows上,我想.DLL是32位的。我们无法调试您没有显示的代码。如果您需要帮助找出代码不起作用的原因,请发布代码。在此之前,您可以阅读MSDN上的文档,特别是有关如何定位库的部分。您的应用程序是32位还是64位?您无法将32位DLL加载到64位进程中(反之亦然)。@SertacAkyuz GetLastError返回126(找不到模块),有趣的是.DLL就在那里。@jlahd我的应用程序是32位运行在64位Windows上,我想.DLL是32位的。我做了一些不同的事情,在加载nss3.DLL之前,我在mozglue.DLL上调用了LoadLibrary,也很有效,也很脆弱。我不知道你为什么不按标准方式来做。我做了一些不同的事情,在加载nss3.dll之前,我在mozglue.dll上调用了LoadLibrary。这也很脆弱。我不知道你为什么不按标准方式做。