【问题标题】:regular dll vs extension dll常规 dll 与扩展 dll
【发布时间】:2011-06-30 22:08:49
【问题描述】:

我有一个使用 ATL 的 DLL (A.dll),但其中不能包含 MFC。它需要一些东西是 MFC,所以我创建了一个名为 B.dll 的MFC regular DLL,它在运行时由 A.dll 自动加载(通过导入库)。

A 需要的 B.dll 部分是 B.dll 中定义的类(foo),该类中有一些使用 MFC 的东西。我可以在 A.dll 中创建一个 foo 对象吗? B 是否需要改为扩展 DLL?

常规 DLL 页面显示:

一个内的所有内存分配 常规 DLL 应保留在 动态链接库; DLL 不应传递给或 从调用可执行文件接收 以下任何一项:

  • 指向 MFC 对象的指针

  • 指向由 MFC 分配的内存的指针

但扩展 DLL 页面显示

客户端可执行文件必须是定义了 _AFXDLL 编译的 MFC 应用程序。A.dll 不能是 MFC 应用程序。

在这种情况下使用常规 DLL 会不会有问题?

谢谢,

布莱恩

【问题讨论】:

    标签: windows dll mfc


    【解决方案1】:

    也许我理解错了,但是如果 A 不能使用 MFC,而 B 提供了一个可以使用的类,那么如何在 A 中实例化一个对象?您是否希望 B 具有创建对象并通过指针将其传递给 A 的工厂函数?在这种情况下,您需要确保 B 对其调用 delete(),而不是 A,因为它们将有两个不同的堆。

    这是一个 COM 对象还是“导入库”是什么意思?我们是在使用 .lib 中的存根还是“导入库”.tlb 中的“常规”dll 方式? (这对我认为的问题并不重要,我只是想描绘一下这种情况)。

    【讨论】:

    • 我最初让 A 创建了一个在 B 中定义的 MFC 对象。我认为这就是导致我的堆错误的原因。我现在将其更改为一个函数,其中对象的生命周期由 B 管理,A 访问是通过导出的函数。它不是一个 com 对象。导入库是由编译器或链接器生成的 .lib 文件,或者当您将某些内容指定为 __declspec(dllexport) 或在 def 文件中时生成的任何文件。然后任何导入它并链接到导入库的东西都会在运行时自动加载 dll。
    • 好的,这很清楚。是的,跨 dll 边界混合 new/delete 有时会产生意想不到的结果。 dll 可能会在某一时刻与其他 dll 共享堆,然后当安装 CRT 的更新时,它开始使用自己的堆(取决于清单设置),从而加剧了这种情况。我认为普遍的智慧是永远不要让另一个模块分配的模块空闲内存,换句话说,就像你说的那样,让每个模块都进行自己的内存管理。如果我没记错的话,带有 _USRDLL/_AFXDLL 的 dll 有一个不同的堆,用于执行特定于 MFC 的操作。
    【解决方案2】:

    看起来常规的 DLL 是正确的选择。

    常规 DLL 的主要问题是,如果将其加载到 MFC 应用程序中,将有两个独立的 MFC 副本和所有元数据。您找到的建议是为了确保元数据查找不会转到错误的副本。在您的场景中不是问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-19
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-05
      相关资源
      最近更新 更多