在 Delphi 中使用接口是否需要 GUID?

发布于 2024-09-04 19:21:14 字数 115 浏览 2 评论 0原文

官方文档说它们是可选的。我知道 COM 互操作需要每个接口有一个唯一的标识符,但我看到的每个接口示例都有一个 GUID,无论它是否与 COM 一起使用?如果 GUID 不与 COM 一起使用,那么包含它有什么好处吗?

The official documentation says they are optional. I know COM interop requires a unique identifier for each interface but every interface example I see has a GUID whether it's used with COM or not? Is there any benefit to including a GUID if its not going to be used with COM?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

像你 2024-09-11 19:21:14

我注意到一些方法,例如 Supports (确定一个类是否符合特定接口)要求您先定义一个 GUID,然后才能使用它们。

此页面通过以下信息确认了这一点:

注意:SysUtils 单元提供了
名为 Supports 的重载函数
上课时返回 true 或 false
类型和实例支持
特定接口表示为
GUID。Supports 函数用于
Delphi 的方式是
运营商。显着差异
是支持功能可以采取
作为正确的操作数 GUID 或
与关联的接口类型
GUID
,而 is 和 as 则取名称
属于一种类型。欲了解更多信息
is 和 as,请参阅类引用。

以下是一些有关接口的有趣信息,其中指出:

为什么需要一个接口
唯一可识别?答案是
简单:因为 Delphi 类可以
实现多个接口。当
应用程序正在运行,必须
是一种获取指针的机制
从一个适当的接口
执行。 找到的唯一方法
如果一个对象实现了一个
接口并获取指向的指针
该接口的实现是
通过 GUID

在两个引号中都添加了强调。

阅读整篇文章也会让您意识到 QueryInterface(需要 GUID)出于引用计数等原因在幕后使用。

I've noticed that some methods such as Supports (to determine if a class conforms to a specific interface) require that you define a GUID before you can use them.

This page confirms it with the following information:

Note: The SysUtils unit provides an
overloaded function called Supports
that returns true or false when class
types and instances support a
particular interface represented by a
GUID.
The Supports function is used in
the manner of the Delphi is and as
operators. The significant difference
is that the Supports function can take
as the right operand either a GUID or
an interface type associated with a
GUID
, whereas is and as take the name
of a type. For more information about
is and as, see Class References.

Here's some interesting information about interfaces, which states:

Why does an interface need to be
uniquely identifiable? The answer is
simple: because Delphi classes can
implement multiple interfaces. When an
application is running, there has to
be a mechanism that will get pointer
to an appropriate interface from an
implementation. The only way to find
out if an object implements an
interface and to get a pointer to
implementation of that interface is
through GUIDs
.

Emphasis added in both quotes.

Reading this entire article also makes you realize that QueryInterface (which requires a GUID) is used behind the scenes for reasons such as reference counting.

别念他 2024-09-11 19:21:14

仅当您需要接口与 COM 兼容时。

不幸的是,这还包括使用 isas 运算符和 QueryInterfaceSupports 函数 - 缺乏这些功能是相当困难的。限制。因此,虽然没有严格要求,但使用 GUID 可能更容易。否则,你只能得到相当简单的用法:

type
  ITest = interface
    procedure Test;
  end;

  ITest2 = interface(ITest)
    procedure Test2;
  end;

  TTest = class(TInterfacedObject, ITest, ITest2)
  public
    procedure Test;
    procedure Test2;
  end;

procedure TTest.Test;
begin
  Writeln('Test');
end;

procedure TTest.Test2;
begin
  Writeln('Test2');
end;

procedure DoTest(const Test: ITest);
begin
  Test.Test;
end;

procedure DoTest2(const Test: ITest2);
begin
  Test.Test;
  Test.Test2;
end;

procedure Main;
var
  Test: ITest;
  Test2: ITest2;
begin
  Test := TTest.Create;
  DoTest(Test);
  Test := nil;

  Test2 := TTest.Create;
  DoTest(Test2);
  DoTest2(Test2);
end;

Only if you need your interface to be compatible with COM.

Unfortunately, that also includes using is, as operators and QueryInterface, Supports functions - the lack of which is rather limiting. So, while not strictly required, it's probably easier to use a GUID. Otherwise, you are left with rather simplistic usage only:

type
  ITest = interface
    procedure Test;
  end;

  ITest2 = interface(ITest)
    procedure Test2;
  end;

  TTest = class(TInterfacedObject, ITest, ITest2)
  public
    procedure Test;
    procedure Test2;
  end;

procedure TTest.Test;
begin
  Writeln('Test');
end;

procedure TTest.Test2;
begin
  Writeln('Test2');
end;

procedure DoTest(const Test: ITest);
begin
  Test.Test;
end;

procedure DoTest2(const Test: ITest2);
begin
  Test.Test;
  Test.Test2;
end;

procedure Main;
var
  Test: ITest;
  Test2: ITest2;
begin
  Test := TTest.Create;
  DoTest(Test);
  Test := nil;

  Test2 := TTest.Create;
  DoTest(Test2);
  DoTest2(Test2);
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文