【问题标题】:Delphi forms in dllsdll中的Delphi表格
【发布时间】:2011-04-27 13:56:23
【问题描述】:

将具有完整功能的表单放在 dll 中是否是个好主意。 主应用程序将调用返回表单对象的 dll 函数。

【问题讨论】:

    标签: delphi


    【解决方案1】:

    在 Delphi 中执行此操作的公认方法是使用包而不是 DLL。

    包本质上是 DLL,但具有允许跨包边界使用 VCL 对象的 Delphi 特定功能。

    尝试使用 DLL 执行此操作会导致包处理的各种问题。软件包的一个缺点是所有模块都必须使用相同版本的 Delphi 编译。但是,如果您想跨模块边界共享对象,那么如果您使用 DLL,您将面临同样的限制。

    Delphi 文档广泛涵盖了packages

    说了这么多,我想补充一点,如果您可以将所有代码放入一个模块(.exe 或 .dll)中,那么它确实让生活变得更加简单。

    【讨论】:

    • 我宁愿说 Delphi 文档没有关于包的有用信息。
    • 我对包的看法是:这是一个很酷的想法,因为它可以消除通过 DLL 共享代码所涉及的许多典型内存管理问题。然而,在实施过程中,我们发现所有的“好东西”都要求包和应用程序之间的耦合过于紧密。例如。有时将新功能滚动到包中需要重新编译应用程序。我相信太多的钱被倒进了包裹的下水道,没有人愿意承认这是一个坏主意。
    • PS:我完全同意单模块方法,除非有其他重要需要填写。
    【解决方案2】:

    添加关于使用包的答案:

    • 仅当主应用程序和所有 dll(插件)均使用 Delphi 编写并且使用相同版本的 Delphi 编写时,才能使用包
    • DLL 可以用任何可以创建它们的编程语言编写,并且可以被任何程序使用,而不管编程语言是什么

    因此,使用 dll 而不是包确实有意义。

    关于实际问题:是的,可以将表单放入 dll 中,它们通常可以正常工作。只需确保不要传递它们,因为它们只是 dll 上下文中的有效对象。您将遇到表单失去焦点或落后于其他表单的奇怪问题。这通常可以通过将窗口句柄从主可执行文件传递给 dll 来解决,然后将其用作表单的父级。

    另请注意:您的 dll 的 TObject 与您的应用程序的 TObject 不同。这同样适用于其他常用的类和变量,例如 (Forms.)Application。

    我已经做到了,腰部疼痛,但这并非不可能。主程序使用 Visual Basic 6 编写,部分模块使用 Delphi 6 编写,其他模块使用 Delphi 7 和 Delphi 2007 编写。

    结论:如果您确定永远不会为您的应用程序和 dll(插件)使用不同于 Delphi 的东西,并且愿意在切换 Delphi 版本时始终重新编译所有内容,那么您应该使用包。否则,使用常规 dll 可能会更好。 (你确定你将永远是唯一一个编写这些 dll 的人吗?也许在某个时候会有一个 dll 的第三方开发人员不拥有他需要的 Delphi 版本。)

    【讨论】:

      【解决方案3】:

      IMO 这有时是一个非常好的主意,也是唯一可行的方法 - 由于其他人提到的原因,我不喜欢软件包,并且对 DLL 非常满意。我目前正在使用 Delphi XE 向用 Delphi 5 编写的应用程序添加功能——它要么使用 DLL,要么用 D5 编写——当然我选择了前者:D5 应用程序调用用 XE 编写的 DLL,其中包含所有最新和最强大的功能。 (我在 Delphi 中所做的第一个项目是通过旧的 Borland Paradox 完成的 - Paradox 应用程序调用了用 Delphi 1 编写的 DLL!)

      但是,我不会将 DLL 中的表单或模块发送回主应用程序 - 我只是向 DLL 模块发送一个结构,该结构包含它完成工作所需知道的内容,以及何时完成以及 DLL 的表单关闭,它清理然后返回一个数字代码或结构返回给调用者,指示成功、失败等(老式但非常有效)。

      通过 DLL 阈值将表单实例从 DLL 传递回您的主应用程序可能会出现问题 - 请注意上面 @dummzeuch 的出色回答,其中提供了一些关于如何协商其中一些问题的好技巧,如果您认为这是您唯一的解决方案。

      【讨论】:

        【解决方案4】:

        +1 表示 David Heffernan 所说的一切。

        从策略上讲,如果您正在实施插件系统,您实际上只需要在外部文件中实施表单(或其他功能)。

        如果您要允许以任何语言编写插件,那么 DLL 是唯一可行的方法。

        如果您的插件系统仅限于使用相同版本 Delphi 的开发人员(也许是同一团队?),那么请使用 BPL。在我看来,Delphi 包的另一个缺点是需要在您的应用程序中部署 VCL BPL,这总是比单个编译模块多 Mb。

        另一方面,如果您想编写一个模块化系统,您仍然可以通过在代码中实现松散耦合和“插件”技术来做到这一点,并且仍然可以编译为单个模块。

        【讨论】:

          【解决方案5】:

          如果您将表单放入普通 dll 中,该表单将无法拦截 TAB 或箭头键。我被告知这是由于 OnKeyDown 没有被传递。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-10-01
            • 1970-01-01
            • 1970-01-01
            • 2017-07-12
            相关资源
            最近更新 更多