Arhn - архитектура программирования

Как преобразовать один интерфейс в другой в Delphi 7?

У меня возникла следующая проблема:

У меня есть класс, который был сгенерирован из файла xsd с помощью мастера привязки данных XML Delphi 7 (New -> Other -> XML Databindng).

Мне нужно найти способ добавить методы в сгенерированный код:

IXMLGlobeSettingsType = interface(IXMLNode)
    ['{9A8F5C55-F593-4C70-85D2-68FB97ABA467}']
    { Property Accessors }
    function Get_General: IXMLGeneralSettingsType;
    function Get_Projector: IXMLProjectorSettingsType;
    function Get_LineMode: IXMLLineDrawingSettingsType;

    { Methods & Properties }
    property General: IXMLGeneralSettingsType read Get_General;
    property Projector: IXMLProjectorSettingsType read Get_Projector;
    property LineMode: IXMLLineDrawingSettingsType read Get_LineMode;

    //procedure SetDefault;   {To be added}
  end;

Интерфейс реализован соответствующим классом, который также генерируется мастером:

TXMLGlobeSettingsType = class(TXMLNode, IXMLGlobeSettingsType)
  protected
    { IXMLGlobeSettingsType }
    function Get_General: IXMLGeneralSettingsType;
    function Get_Projector: IXMLProjectorSettingsType;
    function Get_LineMode: IXMLLineDrawingSettingsType;
  public
    procedure AfterConstruction; override;
  end;

И чтобы определить мои собственные расширения для сгенерированного кода, я определил следующий интерфейс:

IDefaultable = interface
   procedure SetDefault;
end;

Со следующим классом реализации:

DefaultableXMLGlobeSettingsType = class(TXMLGlobeSettingsType, IDefaultable)
  public
    procedure SetDefault;
  end;

Однако я только что понял, что Delphi 7 не позволяет мне преобразовывать один интерфейс в другой (или даже из интерфейса в объект). Таким образом, следующий код вызовет ошибку:

defaultSettings : IDefaultable;    
FGlobeSettingsIntf: IXMLGlobeSettingsType; // FGlobeSettingsIntf is in fact a DefaultableXMLGlobeSettingsType

// some code

defaultSettings := FGlobeSettingsIntf as IDefaultable; // error: operator not applicable to this operand type

Я в значительной степени застрял здесь. Как можно обойти эту ошибку? Есть ли способ (даже уродливый) в Delphi 7 привести интерфейс к объекту, а затем обратно к другому интерфейсу.

20.07.2017

  • ОК принял ваше (извините, Уве!). 21.07.2017
  • Не бери в голову! Дэвид прав - спорить не о чем. 21.07.2017

Ответы:


1
defaultSettings := FGlobeSettingsIntf as IDefaultable;
// error: operator not applicable to this operand type

Эта ошибка указывает на то, что определение IDefaultable не включает GUID. Без GUID невозможно запросить интерфейс, что и делает оператор as в этом контексте.

Оператор as, когда он используется с интерфейсом с правой стороны, реализуется путем вызова IInterface.QueryInterface. Это требует, чтобы GUID был связан с интерфейсом.

Устраните проблему, добавив GUID при объявлении IDefaultable.

21.07.2017
  • Совет: используйте Ctrl + Shift + G в редакторе, чтобы вычислить и вставить новый уникальный GUID под первой строкой типа интерфейса. 21.07.2017
  • @ Дэвид Хеффернан. Принимаю ваш ответ для полноты картины. Ответ Уве тоже весьма полезен. Спасибо Уве! 21.07.2017
  • Фактически, можно реализовать QueryInterface для возврата любого интерфейса, который каким-либо образом может быть связан с GUID. Пользовательский QueryInterface может связывать интерфейс с GUID другими способами, кроме встроенного. Вы описываете обычный (и встроенный) способ, но он может работать совершенно по-другому, и тогда GUID не нужно определять для интерфейса, как это обычно делается в Delphi. Я не знаю, почему кто-то сделал бы это по-другому, но я не об этом. <г> 22.07.2017
  • @Rudy Если вернуться к рассматриваемому вопросу, as приведет к вызову QI с передачей идентификатора GUID, связанного с интерфейсом. Фактически, единственный способ устранить ошибку, не изменяя код, использующий as, - это добавить GUID в интерфейс. 22.07.2017

  • 2

    Вот для чего Supports:

    if Supports(FGlobeSettingsIntf, IDefaultable, defaultSettings) then begin
      defaultSettings.SetDefault;
    end;
    
    20.07.2017
  • Большое спасибо за ваш ответ. Принятие его, потому что это кажется чистым способом приведения из интерфейса в другой, хотя основная причина, по которой мой код не компилировался, была связана с отсутствием GUID (см. Редактирование исходного вопроса). Однако сигнатура опор мне не понятна: function Supports(const Instance: IInterface; const IID: TGUID; out Intf): Boolean; второй параметр - TGUID. В моем случае это IDefaultable. Я что-то упускаю? 20.07.2017
  • @BigONotation тип интерфейса может быть передан в TGUID, и компилятор заменит фактический guid интерфейса 20.07.2017
  • @RemyLebeau Большое спасибо за разъяснения! Эта статистика имеет смысл. 20.07.2017
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..