为什么我的应用程序不需要msado15.dll?

时间:2012-08-16 07:45:36

标签: c++ com

这个程序的stdafx.h有点像这样。

// ...
#import "./lib/64/msado15.dll" rename("EOF", "EndOfFile") no_namespace
// ...

该程序运行正常,没有任何问题。

我很好奇如果删除msado15.dll会发生什么。 所以,我删除了它,程序仍然正常。

我认为为什么程序在没有msado15.dll的情况下工作在同一目录中必须将dll文件加载到其他地方。

为确保dll的确切位置,我使用了“Dependancy Walker”,我发现这个程序根本没有加载msado15.dll。

如果能弄清楚我错过了什么,我会很高兴。

提前致谢。

1 个答案:

答案 0 :(得分:3)

Dependency Walker 只能看到静态DLL依赖项(EXE的imports表中有引用)。如果在运行时通过LoadLibrary加载DLL(或通过延迟加载 - 使用/delayload), Dependency Walker 将无法看到此内容。

#import实际上并没有对DLL施加静态依赖。它在编译时从DLL加载COM类型库信息。这将转换为类库中定义的COM类和接口的C ++绑定。您可以在.tli.tlh目录中将这些文件视为DebugRelease个文件。您可能能够删除DLL文件,并且 - 只要这些文件仍然存在 - VS可能会继续成功构建您的项目。

同样,在运行时,由于#import实际上并没有对DLL施加静态依赖(即:它不会将它添加到EXE中的imports表), Dependency Walker < / em>将无法看到此依赖项。

然而,在运行时,EXE将调用(间接)LoadLibrary,并且(如果DLL丢失)这将导致运行时失败,程序可能会正确处理,或者可能导致程序崩溃。

即使说了这么多,#import只是导入一个COM类型库。 COM类型库定义COM对象中使用的接口,以及这些对象的CLSID值。为了找到实现COM对象的代码,CLSID值使用注册表解析(在HKEY_CLASSES_ROOT\CLSID中。实现COM对象的代码实际上可能不在同一个二进制文件中原始的类型库

这意味着在运行时甚至可能不需要DLL。我认为这种情况很少见。

此外,COM对象可以实现为进程外对象(意味着加载了另一个EXE)。在这种情况下,加载到您的进程中的所有内容都将是为相关接口配置的代理/存根DLL。通常,这些将使用TLB定义(在这种情况下,将加载您的#import - ed DLL);但它们可能在完全不同的DLL中实现。无论哪种方式,DLL都将动态加载,这意味着 Dependency Walker 将无法看到它。

要查看进程加载了哪些DLL,您需要使用SysInternals Process Monitor Process Explorer 等内容。