4

考虑 Windows 上的以下文件组织:

[app folder]
    app.exe
    [folder 'sub']
        com_server.dll
        regular.dll
        helper.dll

还假设以下内容:

  • com_server.dll 和regular.dll 都静态链接到helper.dll 中的函数,因此helper.dll 会在它们存在时被加载。
  • app.exe 没有静态依赖项。
  • com_server.dll COM 对象在 Windows 中注册
  • 文件夹 'sub' 不在系统路径中。

考虑以下情况:

  1. app.exe 调用 LoadLibrary("sub/regular.dll")。这将失败,因为 Windows 将无法找到 helper.dll,这与文档中的 DLL 搜索过程一致。
  2. app.exe 调用 CoCreateInstance 以创建在 com_server.dll 中实现的对象。这成功并加载了 helper.dll。

主要问题:为什么案例 2 有效?COM 服务器案例的依赖 DLL 搜索过程的细节是什么?

看起来,当使用 CoCreateInstance 创建 com 对象时,实现 dll 的文件夹以某种方式添加到依赖项的搜索路径中。这是正在发生的事情吗,这是有保证的吗?我在任何地方都找不到任何讨论此案例的文档。

4

1 回答 1

0

让我们看一下MSDN 上 LoadLibrary的文档:

如果字符串指定了完整路径,则该函数仅在该路径中搜索模块。如果字符串指定了相对路径或不带路径的模块名称,则该函数使用标准搜索策略来查找模块;有关详细信息,请参阅备注。

好的,这就解释了上面 #1 的行为。如果你说过:

LoadLibrary("C:\\program files\\AppFolder\\Sub\\com_server.dll")

然后就会找到您的依赖 DLL,并且 LoadLibrary 会成功。

至于 COM 如何在 #2 上取得成功,这实际上取决于 com_server.dll 如何在注册表中为 InProcServer32 键注册。如果它是文件的完整路径,则 LoadLibrary 将按上述方式工作。如果它是相对路径,那么我怀疑 COM 可能会做很多事情来使查找像您这样的 DLL 工作。

一种可能的可能性是 CoCreateInstance 在调用LoadLibraryEx时设置了LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR标志。它甚至可以使用不同的标志组合多次调用 LoadLibrary(Ex)。

此外,鉴于 CoCreateInstance 是一个系统 API,它完全有可能拥有 LoadLibrary 的私有内部版本,允许备用搜索路径。

于 2012-12-19T06:37:16.303 回答