【问题标题】:Delphi Interfaces and DLL'sDelphi 接口和 DLL
【发布时间】:2014-02-27 16:50:15
【问题描述】:

我正在尝试找出一种将对象从主应用程序传递到 DLL(对于插件系统)的安全方法。 这个想法是在 dll 中使用主应用程序的 TZConnection(从 Zeos Lib 访问数据库)。

我宁愿不使用Runtime Packages,而且DLL必须是要走的路(我不需要BPL每次都需要重新编译,也不知道如何使用COM)。

有人告诉我,使用接口可以做到这一点。

我以前从未使用过它们,但一直在弄乱它,并设法做到了......但是,我不知道我是否做得对(如,安全)。

这是我的接口单元。

unit PluginIntf;

interface

uses
    ZConnection, ZDataSet;

type
    IQueryResult = interface   ['{743AB77E-7897-403E-A0D9-4D02748E565D}']
      function GetRecordCount: Integer;
      function GetDataSet: TZQuery;
    end;

    IPluginHost = interface   ['{A5A416B4-437E-4A1E-B228-0F94D54840B0}']
      function RunSql(const SQLString:WideString): IQueryResult;
    end;

    IPlugin = interface   ['{8D9591C3-5949-4F0A-883E-6ABD02597846}']
      function GetCaption: WideString;
    end;

implementation

end.

在 IQueryResult 中,我传递了一个 TZQuery。它有效,但是......它安全吗? 有没有其他方法可以将它包装在接口中?

谢谢 努诺·皮卡多

【问题讨论】:

  • TZQuery 是 Zeos Lib 的一部分。它是 TDataset 的后代,用于从 ??SQL 服务器获取查询结果。
  • 这段代码最初来自我在 Embarcadero 论坛的this discussion。正如我在讨论中反复告诉你的那样,不要暴露对跨 DLL 边界的对象的直接访问,但你会继续这样做。停下来!应用程序直接创建的任何对象都只能在应用程序的代码中直接访问。由 DLL 直接创建的任何对象都只能在 DLL 的代码中直接访问。任何需要共享的对象都应该封装在一个隐藏它的接口中。
  • 嗨 Remy,感谢您在这里回复,再次感谢您在那边的回复。我在那边听到了你的声音,这就是为什么我一直在寻求帮助,在那里,现在在这里。我只是不知道,也找不到其他地方,如何将它包装在界面中。就像我告诉你的那样,我从来没有使用过接口,这就是我寻求帮助的原因——我只是不知道该怎么做。尽管如此,如果没有你的帮助,我仍然无法到达我所做的事情,而且我现在对接口有了更多的了解。只是不足以理解它的所有权力和局限性。谢谢!
  • 当@RemyLebeau 说“...应该被包装在一个隐藏它的界面中”时,他 NOT 指的是 接口 语言结构。他指的是两个事物交流所依据的规则的概念概念。这通常也称为“接口”,因此我可以理解您的困惑。但是这种接口只是函数和过程的集合,它们提供对其他模块内部对象的间接访问。
  • 谢谢克雷格。我想我现在明白了,所以我转向 B 计划:不尝试不访问另一个模块的对象,每个模块都将创建和销毁它自己的对象,我将只使用原始数据类型的接口(整数, bool) 和 COM 管理的 WideString。

标签: delphi memory-management plugins dll interface


【解决方案1】:

TZQuery 是一个类。因此,除非您使用运行时包,否则跨模块边界传递一个是不安全的。使用带有 DLL 的类,您实际上有两种不同的类型,每个模块中都有一种。

您认为接口对此是安全的是正确的,但您需要将自己限制为 DLL 互操作安全类型。即简单类型、记录、指向数组的指针、接口或这些类型的组合。

您需要将TZQuery 包装成一个公开其功能的接口。

【讨论】:

  • 感谢您的回复。因此,即使使用接口,也只有简单的数据类型。这实际上意味着我不能使用主应用程序连接在 dll 中使用数据集,因为我无法将整个类“转换”为简单的数据类型并在 dll 中重新创建它。是这样吗,还是有其他方法可以做到这一点?
  • 您需要使用有效的互操作类型来包装数据集功能。例如用接口包装它。
  • 关于“如何”的任何想法? :) 这正是我不知道该怎么做。如何将一个类包装在一个接口中,并设法在另一个模块上使用它?
  • 1.定义一个接口。 2. 创建一个实现接口的类。 3. 给类一个单独的字段,它是被包装类型的对象。 4. 通过将接口的方法转发给被包装的对象来实现它们。
  • @nunopicado:我向您展示了如何完全执行 David 所描述的示例。我之前给你的例子有什么不清楚的地方吗?
猜你喜欢
  • 2011-10-01
  • 1970-01-01
  • 2014-03-22
  • 2011-08-11
  • 1970-01-01
  • 2012-07-06
  • 2022-11-25
  • 2012-07-28
  • 1970-01-01
相关资源
最近更新 更多