【问题标题】:Can I use one DLL process per executable我可以为每个可执行文件使用一个 DLL 进程吗
【发布时间】:2020-11-19 13:24:00
【问题描述】:

我正在使用 DLL 在我的游戏中启用模组。在 Visual Studio 链接器中,我将 DLL 的 .lib 与可执行文件链接。一切正常,但添加多人游戏会出现问题。由于它是 DLL,如果我没记错的话,它只是整个 Windows 的一个进程。但我需要“client.exe”和“server.exe”在不共享相同 DLL 的情况下运行。我尝试为“server.exe”重命名 DLL,但后来告诉我它无法加载它,因为它仍然需要“未重命名”的 DLL。我怎样才能为“client.exe”和一个“server.exe”创建一个 DLL,而不让它们共享导致错误的相同?如果我创建 DLL 的副本并将其放在其他地方,它会有什么不同吗?从我读过的内容来看,它仅取决于名称而不是路径(也许我错了)。

【问题讨论】:

  • 共享dll有什么问题?从技术上讲,它是否是相同的内存页面并不重要......客户端和服务器仍然是两个不同的进程。
  • DLL 不在多个进程之间共享。多个进程可能使用磁盘上的同一个 DLL 文件,但每个进程将 它自己的 DLL 副本加载到内存中。因此,无论您遇到什么错误,都可能是由于 DLL 编码中的错误,而不是共享同一 DLL 文件的客户端和服务器进程。
  • @CherryDT 他们共享相同的记忆,但我需要他们有不同的记忆
  • @MichaeltLoL DLL 默认情况下不相互共享内存,您必须自己明确设置,使用共享段或内存映射视图等。到目前为止,您的所有假设/预期似乎是错误的。那么,您遇到的实际问题是什么?
  • @RemyLebeau 好的,谢谢!

标签: c++ windows visual-studio dll


【解决方案1】:

DLL 是一个由几个部分组成的二进制文件。这些部分可以分为两种类型。一是与绝对地址寻址无关,因此可以被多个进程共享;另一个与绝对地址寻址有关,每个进程必须有自己的副本供独占使用。

编译 DLL 时,编译器和链接器已经标记了这两类段。因此,加载DLL时,加载器知道哪些段只需要物理内存地址空间中的一个副本供多个进程共享(映射到每个进程的内存逻辑地址空间,所以逻辑地址可以不同);哪些部分必须是 进程使用自己的私有副本。完美解决了DLL多进程共享问题。

加载 DLL 的每个进程都将其映射到其虚拟地址空间。进程将DLL加载到它的虚拟地址后,就可以调用导出的DLL函数了。

系统为每个 DLL 维护每个进程的引用计数。当线程加载 DLL 时,引用计数加一。当进程终止或引用计数变为零时(仅限运行时动态链接),DLL 将从进程的虚拟地址空间中卸载。

与任何其他函数一样,导出的 DLL 函数在调用它的线程的上下文中运行。因此,适用以下条件:

  • 调用 DLL 的进程的线程可以使用打开的句柄 通过 DLL 函数。同样,由任何线程打开的句柄 调用进程可以在DLL函数中使用。
  • DLL 使用调用线程的堆栈和虚拟地址 调用进程的空间。
  • DLL 从虚拟地址空间分配内存 调用进程。

如果你想在动态链接库中使用共享内存,你可以参考Microsoft Docs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 2010-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多