Действительно ли GUID необходимы для использования интерфейсов в Delphi?

В официальной документации говорится, что они дополнительные. Я знаю взаимодействующий с COM, требует уникального идентификатора для каждого интерфейса, но каждый интерфейсный пример, который я вижу, имеет GUID, используется ли он с COM или нет? Там какое-либо преимущество к включению GUID если не попытка использоваться с COM?

19
задан Kenneth Cochran 7 June 2010 в 18:46
поделиться

2 ответа

Я заметил, что некоторые методы, такие как Supports (для определения соответствия класса определенному интерфейсу), требуют, чтобы вы определили GUID, прежде чем вы сможете их использовать.

Эта страница подтверждает это следующей информацией:

Примечание: Блок SysUtils предоставляет перегруженную функцию под названием Supports которая возвращает true или false, когда класс типы и экземпляры поддерживают определенный интерфейс, представленный GUID. Функция Supports используется в по аналогии с операторами Delphi is и as операторы. Существенное отличие заключается в том, что функция Supports может принимать в качестве правого операнда либо GUID, либо тип интерфейса, ассоциированный с GUID, тогда как is и as принимают имя типа. Для получения дополнительной информации о is и as см. в разделе Ссылки на классы.

Вот интересная информация об интерфейсах, которая гласит:

Почему интерфейс должен быть уникально идентифицируемым? Ответ прост: потому что классы Delphi могут реализовывать несколько интерфейсов. Когда приложение работает, должен быть быть механизм, который будет получать указатель на соответствующий интерфейс из реализации. Единственный способ узнать. узнать, реализует ли объект интерфейс и получить указатель на реализацию этого интерфейса через GUID.

Подчеркивание добавлено в обеих цитатах.

Читая эту статью целиком, вы также понимаете, что QueryInterface (который требует GUID) используется за кулисами по таким причинам, как подсчет ссылок.

19
ответ дан 30 November 2019 в 04:24
поделиться

Только если вам нужно, чтобы ваш интерфейс был совместим с 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;
7
ответ дан 30 November 2019 в 04:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: