2012-09-07 52 views
2

我需要从另一个DLL中加载一个DLL。诱惑是将它加载到DllMain中,但已经有令人信服的文档说明它是一个“坏主意”。有从另一个DLL中加载DLL的最佳做法吗?

冒着问一个不是很具体的问题:是否有从另一个DLL加载DLL的最佳做法?

在我们当前的项目中,我们的主DLL有一个类。我从该类的构造函数中加载第二个DLL。但是,由于该类可以在DLL中多次实例化,因此我在其周围保留一个变量以指示是否先前加载了DLL,以便不再次调用LoadLibrary。这不知何故不觉得这是一个好的解决方案,因此我的问题。

+2

对于它的价值,你的解决方案根本不算什么 - 这是非常普遍的。这是一个简单而优雅的方法来解决这个问题,而不需要在DLL中增加一些额外的初始化函数。我会把它放在像'EnsureOtherDLLLoaded'之类的函数中。 – tenfour

+1

你的解决方案很好。事实上,你甚至不需要跟踪它是否已经被加载。在这个过程中再次调用LoadLibrary是很好的。 Windows将为该库保留引用计数,并且不会卸载它,直到FreeLibrary调用的次数与LoadLibrary调用的次数相匹配。 –

回答

3

这取决于你的DLL。 基本上,你有以下选择:针对DLL的LIB

  1. 链接自动
  2. Load当你的库加载,卸载,然后再将其卸载
  3. 负载使用前其他DLL其他DLL加载它,然后卸载

如果您选择1,如果DLL2在尝试加载DLL1时丢失,您会得到非常奇怪的消息,例如“无法加载DLL1”。而客户永远不会知道这是因为缺少DLL2。所以我不喜欢使用这个解决方案,如果你不能100%确定DLL2安装正确的话。

但是,当您手动加载DLL2(LoadLibrary)时,您将有机会呈现有意义的消息。

如果在DLL中有明确的入口和出口点,则可以选择2。如果您的DLL导出一个或很少的函数,即为其他对象创建工厂的函数,就是这种情况。然后你可以加载/卸载工厂。

如果这不会导致您频繁地执行此加载/卸载,您可以选择3。

此外,您不需要只保留一个DLL2句柄。您可以多次调用LoadLibrary/FreeLibrary,它是执行引用计数的框架。

因此,根据您的情况,您可以选择这三种解决方案之一。只有当您没有明确的入口点并且您正在调用需要DLL2的函数时,您才必须使用原始解决方案。

+0

这听起来像你告诉他他可以随意多次LoadLibrary多次,从0递增一个变量,并且框架将为他引用计数,并且不会有大量开销。然后在退出时,随着变量增加,多次调用FreeLibrary。 –

+0

当然有一些开销,但它相对较小。我刚刚检查过它:第二个LoadLibrary返回与第一个(p1)相同的指针(p2)。所以这个库不是第二次加载,只是同一个habdle被重用。 然后你可以FreeLibrary(p2)并继续使用p1。当然,加载和卸载的总数应该匹配。 – Steed

+0

第二个LoadLibrary是否会导致第二个DLLMain第二次执行? –