Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Можно ли по имени published метода узнать, что он abstract;  [new]
Polesov
Member

Откуда:
Сообщений: 357
Добрый день.

Есть некий механизм вызова методов классов по их имени. Параметры, передаваемые в такие методы при их вызове, строго оговорены.
В базовом типе класса определены виртуальные абстрактные методы, которые в потомках не всегда реализованы.
В силу ошибки для вызова метода потомка может быть передано имя виртуального абстрактного метода.

Поискал информацию по этому вопросу - вроде бы адрес у всех абстрактных методов указывает на заглушку генерации exception, т.е. по идее должен быть одинаковым, но оказалось, что это не так:
type
  TMethods = class( TPersistent )
  published
    procedure Method1( Sender : TObject ); virtual; abstract;
    procedure Method2( Sender : TObject ); virtual; abstract;
    procedure Method3( Sender : TObject ); virtual; abstract;
    procedure Method4( Sender : TObject ); virtual; abstract;
  end;


TMethods.MethodAddress( Method1 ) = $5DB61C
TMethods.MethodAddress( Method2 ) = $5DB624
TMethods.MethodAddress( Method3 ) = $5DB62C
TMethods.MethodAddress( Method4 ) = $5DB634

В VMT, как я понял, такой информации нет.

Можно ли зная тип класса и имя метода выяснить, является ли он виртуальным абстрактным?

Delphi XE7 ежличо

С уважением, Polesov.
17 фев 17, 13:42    [20221140]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
DimaBr
Member

Откуда:
Сообщений: 10136
Polesov
В силу ошибки для вызова метода потомка может быть передано имя виртуального абстрактного метода.

Что бы не было ошибки, сделать виртуальные методы не абстрактными. Абстрактные методы подразумеваю реализацию в наследнике. Если такой реализации нет, то пусть дёргается пустой метод
17 фев 17, 13:45    [20221152]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 22617
Сравнить адреса от базового класса с адресами из наследника не предлагать?
17 фев 17, 13:47    [20221157]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 9560
Polesov
Параметры, передаваемые в такие методы при их вызове, строго оговорены.
В базовом типе класса определены виртуальные абстрактные методы,
IDispatch + позднее связывание и тогда ситуация
Polesov
абстрактные методы, которые в потомках не всегда реализованы.
Будет просто невозможна
17 фев 17, 14:05    [20221250]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
GunSmoker
Member

Откуда:
Сообщений: 2869
Определить можно, только я не пойму что вы с этой информацией делать будете. Ошибку возвратите? Ну так вызовите метод, он вам ошибку и вернёт.
17 фев 17, 14:05    [20221254]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Polesov
Member

Откуда:
Сообщений: 357
DimaBr
Абстрактные методы подразумеваю реализацию в наследнике.
Это да, но рассматривается ситуация, когда допущена ошибка и возможность диагностики такой ошибки.

DimaBr
Если такой реализации нет, то пусть дёргается пустой метод
Это тоже не выход, т.к. при неком действии пользователя будет происходить вызов пустого метода. Уж лучше exception.
17 фев 17, 14:14    [20221311]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Polesov
Member

Откуда:
Сообщений: 357
wadman
Сравнить адреса от базового класса с адресами из наследника не предлагать?

Тоже не выход - есть цепочка из 3 наследников базового класса.
Вызов метода 2-го наследника из экземпляра 3-го наследника вполне легален.
17 фев 17, 14:16    [20221322]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
GunSmoker
Member

Откуда:
Сообщений: 2869
Ээээ... выброс EAbstractError - это, что, недостаточный признак возникновения ошибки?
17 фев 17, 14:17    [20221327]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 22617
Polesov
Вызов метода 2-го наследника из экземпляра 3-го наследника вполне легален.

Что? Если во 2-ом перекрыт, то он уже не абстрактный.
17 фев 17, 14:18    [20221330]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Polesov
Member

Откуда:
Сообщений: 357
_Vasilisk_, в принципе выход, но потребуется некоторый объем переделок. В данной ситуации определить факт, что метод является virtual; abstract; было бы лучшим решением.
17 фев 17, 14:18    [20221334]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Polesov
Member

Откуда:
Сообщений: 357
GunSmoker
Определить можно,

Был бы весьма признателен за указание направления, куда копать

GunSmoker
только я не пойму что вы с этой информацией делать будете

Имена таких классов и используемых методов хранятся в БД - можно было бы в приложении реализовать функцию путем перебора выявления виртуальных абстрактных методов. Это было бы гораздо эффективнее, нежели чем проверять на работоспособность все кнопки и пр. Это лучше, чем exception возникнет у заказчика.
17 фев 17, 14:25    [20221364]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 22617
Polesov
Это лучше, чем exception возникнет у заказчика.
try except
17 фев 17, 14:26    [20221372]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Polesov
Member

Откуда:
Сообщений: 357
GunSmoker
Ээээ... выброс EAbstractError - это, что, недостаточный признак возникновения ошибки?

Ошибкой является использование для вызова имени метода, который является виртуальным абстрактным.
17 фев 17, 14:29    [20221385]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Polesov
Member

Откуда:
Сообщений: 357
wadman
Polesov
Это лучше, чем exception возникнет у заказчика.
try except

Цель не подавить exception, а выявить использование виртуальных абстрактных методов.
17 фев 17, 14:34    [20221413]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
DimaBr
Member

Откуда:
Сообщений: 10136
Всё равно ничего не понятно.
У вас есть класс и наследники не должны получать EAbstractError ?
Или у вас есть некий механизм, который дёргает методы класса по их имени и тут не должна выскакивать ошибка ?
17 фев 17, 14:36    [20221425]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Barlone
Member

Откуда:
Сообщений: 861
Polesov, вы не собираетесь вызывать метод, а хотите определить, не является ли он абстрактным, чтобы занести в некий список (и показать в пользовательском интерфейсе)?
17 фев 17, 14:37    [20221430]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Polesov
Member

Откуда:
Сообщений: 357
wadman
Polesov
Вызов метода 2-го наследника из экземпляра 3-го наследника вполне легален.

Что? Если во 2-ом перекрыт, то он уже не абстрактный.


Тогда поясните свою же фразу
wadman
Сравнить адреса от базового класса с адресами из наследника не предлагать?

Видимо, я не так понял. И еще - базовый класс содержит не только абстрактные методы.
17 фев 17, 14:38    [20221435]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Polesov
Member

Откуда:
Сообщений: 357
DimaBr
Всё равно ничего не понятно.
У вас есть класс и наследники не должны получать EAbstractError ?
Или у вас есть некий механизм, который дёргает методы класса по их имени и тут не должна выскакивать ошибка ?

Назначение вызова метода происходит в неком режиме конструирования. Само имя метода выбирается из списка, который по факту может содержать имена абстрактных методов. Задача заключается в том, что бы выявить в списке имена абстрактных методов.

Повторюсь - занесение в список абстрактного метода является ошибкой.
17 фев 17, 14:41    [20221464]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Polesov
Member

Откуда:
Сообщений: 357
Barlone
Polesov, вы не собираетесь вызывать метод, а хотите определить, не является ли он абстрактным, чтобы занести в некий список (и показать в пользовательском интерфейсе)?

Да, но не "показать в пользовательском интерфейсе", а выявить места вызовов абстрактных методов.
17 фев 17, 14:43    [20221476]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
GunSmoker
Member

Откуда:
Сообщений: 2869
Polesov,

procedure TForm1.Button1Click(Sender: TObject);

  function AbstractError: Pointer;
  asm
    mov EAX, OFFSET System.@AbstractError;
  end;

var
  P: procedure of object;
begin
  P := Self.SomeVirtualMethod;
  if TMethod(P).Code = AbstractError then
    raise EAbstractError.Create('V1 is abstract');
end;
17 фев 17, 14:43    [20221478]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Polesov
Member

Откуда:
Сообщений: 357
GunSmoker, премного благодарен.
17 фев 17, 14:45    [20221487]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Barlone
Member

Откуда:
Сообщений: 861
https://rsdn.org/article/Delphi/delphiabs.xml
17 фев 17, 14:54    [20221533]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Polesov
Member

Откуда:
Сообщений: 357
Barlone, спасибо за ссылку.
17 фев 17, 14:58    [20221556]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 1765
Barlone,

о, rsdn заработал
17 фев 17, 15:25    [20221719]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли по имени published метода узнать, что он abstract;  [new]
Polesov
Member

Откуда:
Сообщений: 357
GunSmoker
  P := Self.SomeVirtualMethod;


Не совсем то
  P := Self.SomeVirtualMethod;
    mov  eax, [eax]
    mov  eax, [eax+$00000140]

Вся заковыка в константе $00000140 - она известна компилятору на этапе раннего связывания.
В моем же случае известен class of и имя метода, т.е. позднее связывание.
17 фев 17, 15:32    [20221777]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить