【问题标题】:How can I automatically load DLLs from a subdirectory?如何从子目录自动加载 DLL?
【发布时间】:2010-10-10 10:34:43
【问题描述】:

在 Visual Studio 中,您创建一个 .dll 项目,它会创建一个 .dll 和 .lib 文件。您静态链接到 .lib,如果 .dll 与 .exe 位于同一文件夹中,则一切正常。

我怀疑如果 .dll 在 System32 或任何其他 PATH 文件夹中(请确认或正确),一切都会正常工作。

但问题是:我希望我的 exe 在 ./DLLS/ 文件夹中找到 .dll,也就是说,如果我的 exe 在 ....../MyApp/MyApp.exe 中,那么它应该寻找.dll 在...../MyApp/DLLS/MyDll.dll。我不想在路径中包含 DLLS 文件夹。有什么办法可以做到这一点吗?

请注意,我不希望明确使用 LoadLibrary,因此我无法在此处指定路径。

提前感谢您的帮助。

【问题讨论】:

标签: c++ visual-studio dll


【解决方案1】:

这是 Win32 应用程序在查找 DLL 时的默认顺序:

http://msdn.microsoft.com/en-us/library/7d83bc18(VS.80).aspx

所以根据这个,另一种方法可能是调用 SetCurrentDirectory 或 SetDllDirectory。但为了使其工作,您必须使用延迟加载库功能(您在 Visual Studio 的项目设置中指定)。延迟加载库意味着 DLL 仅在程序需要时加载,而不是在程序启动时自动加载。

【讨论】:

  • 你是在暗示除非我使用延迟加载,否则我无法达到我想要的效果?
  • @Armen:如果您不(或不能)延迟加载库,那么它将是加载时的依赖项,在加载进程时会加载。这将在您的任何代码执行之前发生,因此您将无法调用 SetDllDirectory 并且加载将失败。如果您不需要立即使用 DLL 的功能(即在 main 之前),则可以将其设为延迟加载依赖项。
  • @Chris:好的,其实我不需要在main之前的dll的功能,所以我可以在main的第一个语句中添加SetDllDirectory,一切都会好起来的。我明白了,但是在 main 之前需要功能的理论案例呢?除了将dll放在同一个文件夹中或将目录添加到PATH之外,没有其他办法吗?那会很奇怪...我的意思是,肯定有一个我找不到的配置属性...
  • @Armen:除了LoadLibrary 以及您在帖子中提到的内容之外,我认为 Windows 加载程序并不是那么可配置的。我认为库必须成为真正的加载时依赖项是非常罕见的,因此没有太多需要使其高度可配置。此外,您始终可以使用GetEnvironmentVariable/SetEnvironmentVariable您的进程 设置PATH。这样,您可以修改加载程序搜索路径,而无需用户这样做,也不会影响其他进程。
  • @Chris:哦,我从来没有意识到我只能为我的流程更改路径。非常感谢。我接受你的回答:)
【解决方案2】:

您可以为此使用SetDllDirectory。加载程序将使用您在加载库时指定的附加目录。但是,只能有一个附加目录,因此您需要确保稍后在您的应用程序中没有其他对此的调用,否则您指定的目录将被忽略。

如果该 API 不允许相对目录(我不确定),您始终可以使用 NULL 第一个参数调用 GetModuleFileName 以获取当前正在执行的程序的文件名。通过一些字符串操作,您可以获得 DLLs 文件夹的绝对路径。

【讨论】:

  • 我应该在哪里使用它?在尝试加载 dll 之前,对吧?但在所描述的场景中(静态链接到自动加载 dll 的 lib),dll 在启动时加载...
  • @Armen:好点,是的,应该在加载 DLL 之前完成。如果您不立即在应用程序中使用 DLL,则可以将其指定为延迟加载依赖项(请参阅msdn.microsoft.com/en-us/library/yx9zd12s.aspx)。这将阻止 DLL 加载,直到您第一次调用它。这类似于调用LoadLibrary,但它是自动为您完成的。
猜你喜欢
  • 2013-06-29
  • 1970-01-01
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 2012-10-24
  • 2011-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多