2010-06-07 105 views
18

官方文档称它们是可选的。我知道COM interop需要每个接口的唯一标识符,但是我看到的每个接口示例都有一个GUID,不管它是否与COM一起使用?如果不包含GUID,是否有任何好处?是否需要在Delphi中使用GUID?

回答

18

我注意到一些方法,如Supports(确定一个类遵循特定的接口)要求你定义一个GUID才可以使用他们。

注::

This page以下信息证实了这一点的SysUtils单元中提供了一个 重载函数调用支持 返回真或假时类 类型和实例支持表示的 特定接口一个 GUID。支持功能用于 德尔福的方式是和 运营商。的显著差异 是,支架函数可以采取 作为右操作数任一个GUID或 与 GUID相关联的接口的类型,而是并作为取的名字的类型 。有关 is和as的更多信息,请参见Class References。

这里的一些interesting information about interfaces,其中规定:

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

强调添加在两个引号中。

阅读这篇文章也让你意识到QueryInterface(它需要一个GUID)在幕后出于诸如引用计数的原因而被使用。

+1

另外,值得注意的是,试图在接口中使用'is'或'as'类型转换涉及其中的一个调用(我忘记了这些调用),因此您需要一个GUID来执行此操作。 – 2010-06-07 18:58:32

+4

所以简短的答案是,虽然GUID是可选的不使用它们限制了你可以用接口做什么。 – 2010-06-07 20:00:14

+0

需要使用'Supports'函数是我为接口定义GUID的唯一原因。 – 2012-04-16 09:51:42

6

只有当你需要你的接口是compatible with COM

不幸的是,这还包括使用is,as运营商和QueryInterface,Supports职能 - 缺乏是相当有限的。所以,虽然没有严格要求,但使用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; 
+0

这是不对的;请参阅@ eagle的答案。如果没有GUID,可以使用非COM接口的唯一方法是不安全的硬性强制转换。 – 2010-06-07 19:12:36

+1

如果我在上面添加的示例中存在任何不安全的情况,请让我知道,谢谢。 – 2010-06-07 19:35:24

+0

@Craig:我不确定接口中是否存在“不安全的硬转换”,因为编译器仍然需要某种方法来定位正在使用的接口的接口表。 – 2010-06-07 20:20:15