Dependency Walker只能查看静态 DLL 依赖项(在 EXE 的导入表中有引用)。如果在运行时通过LoadLibrary
(或通过延迟加载——使用/delayload
)加载 DLL,Dependency Walker将无法看到这一点。
#import
实际上并没有对 DLL 施加静态依赖。它在编译时从 DLL 加载 COM 类型库信息。这被转换为类型库中定义的 COM 类和接口的 C++ 绑定。您可以在or目录.tli
中看到这些.tlh
文件。您可能能够删除 DLL 文件,并且——只要这些文件仍然存在——VS 可能会继续成功构建您的项目。Debug
Release
同样,在运行时,由于#import
实际上并未对 DLL 施加静态依赖(即:它不会将其添加到 EXE 中的导入表中),因此Dependency Walker将无法看到此依赖。
但是,在运行时,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之类的东西。