Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.05.02;
Скачать: [xml.tar.bz2];

Вниз

Интерфейсы и классовые функции   Найти похожие ветки 

 
REA ©   (2004-04-14 16:35) [0]

Нужно получить информацию о классе, до его создания (аналог ClassName). Известно, что класс поддерживает некий интерфейс, но получить его без создания класса не удается. Явно преобразовывать класс к типу нельзя. Получить ссылку на классовый метод в виде Pointer через MethodAddress удается, но корректно преобразовать и вызвать тоже не получается.


 
Тимохов ©   (2004-04-14 16:38) [1]


> REA ©   (14.04.04 16:35)  

вы думаете реально что-то тут сказать?
вы конечно сильно потрудились задавая вопрос...


 
REA ©   (2004-04-14 16:46) [2]

Хм. Попробую изложить ииначе:
Требуется получить информацию о классе (через классовую функцию).
Сам класс неизвестного типа - т.е. не унаследован от общего предка и заранее неизвестно есть у него эта функция или нет.
Приходит в голову два метода:
1) реализовать некий интерфейс и, если он поддерживается, то вызвать его функцию.
2) Получить указатель на published метод по его имени и вызвать.

В первом случае я не смог получить интерфейс (или метод интерфейса) без создания экземпляра класса, а во втором не знаю как преобразовать укзатель к Class Function заданного типа.


 
Тимохов ©   (2004-04-14 16:50) [3]


> В первом случае я не смог получить интерфейс (или метод
> интерфейса) без создания экземпляра класса

логично - интерфейс сам по себе не живет - только над объектом.

Разрешите спросить - откуда такая задача?

Не пойму фразу "Требуется получить информацию о классе (через классовую функцию)."

Что значит "через классовую функцию"?

Может еще попробуете углубиться в  объяснениях?


 
Гаврила   (2004-04-14 16:53) [4]

Ну так нужно значит отнаследовать класс от общего предка, и сделать виртуальную классовую функцию.


 
REA ©   (2004-04-14 16:53) [5]

>логично - интерфейс сам по себе не живет - только над объектом.

Ну почему - можно получить AClass.GetInterfaceEntry(IID), только потом еще придется разбирать самому.

>Что значит "через классовую функцию"?

TSomeClass = Class
Published
 Class Function GetSomeClassInfo: String;
End;


 
VMcL ©   (2004-04-14 16:54) [6]

>>REA ©  (14.04.04 16:46) [2]

Почему экземпляр класса нельзя создавать?


 
WebErr ©   (2004-04-14 16:54) [7]


> Тимохов ©   (14.04.04 16:50) [3]

:)
Не издевайтесь!!! :))))


 
REA ©   (2004-04-14 16:55) [8]

>Ну так нужно значит отнаследовать класс от общего предка, и сделать виртуальную классовую функцию.

Да вот как раз и не получается - мне нужно добавить свою функциональность к готовым компонентам. Множественного наследования тут нет.


 
REA ©   (2004-04-14 16:56) [9]

>Почему экземпляр класса нельзя создавать?

Нет смысла - каждый раз создавать компонент, чтобы получить ClassName, например это слишком.


 
VMcL ©   (2004-04-14 17:01) [10]

>>REA ©  (14.04.04 16:56) [9]

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


 
Тимохов ©   (2004-04-14 17:05) [11]


> Нет смысла - каждый раз создавать компонент, чтобы получить
> ClassName, например это слишком.


Что-то вы странное говорите.
"Нет смысла", значит вы можете создать, но считаете это не нужным.
Если вы можете создать, то значит вы знаете класс, а если знаете класс, то вы можете у класса брать classname (он же тоже классовый метод).

или я что-то не понимаю.


 
default ©   (2004-04-14 17:06) [12]

"Получить ссылку на классовый метод в виде Pointer через MethodAddress удается, но корректно преобразовать и вызвать тоже не получается"
вот как это делается
...

TMyObj = class
published
  class procedure PutHello;
end;

TProc = procedure;

...

class procedure TMyObj.PutHello;
begin
Form1.Caption := "Hello"
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
TProc(TMyObj.MethodAddress("PutHello"))
end;

...


 
VMcL ©   (2004-04-14 17:08) [13]

>>default ©  (14.04.04 17:06) [12]

Вызывать метод, как обычную процедуру - оригинально.


 
default ©   (2004-04-14 17:13) [14]

VMcL ©   (14.04.04 17:08) [13]
передаётся указатель на код метода?что же делать?!)))


 
Юрий Зотов ©   (2004-04-14 17:13) [15]

Не вижу проблемы.

class function ClassName: ShortString;

Это классовый метод, дает имя класса (то есть - полную информацию о классе), для его вызова создавать экземляр класса не требуется и она есть у TObject (то есть - у ВСЕХ классов).

Что же еще нужно-то?


 
default ©   (2004-04-14 17:19) [16]

VMcL ©   (14.04.04 17:08) [13]
штука в том что по умолчанию классовому методe указатель на класс передаётся через регистр(EAX)(не через стек)
поэтому мы можем вызвать его и как процедуру(если не исп-ся EAX)


 
VMcL ©   (2004-04-14 17:21) [17]

>>default ©  (14.04.04 17:19) [16]

Можно в носу опасной бритвой ковыряться. Ну и что?


 
Тимохов ©   (2004-04-14 17:23) [18]


> VMcL ©   (14.04.04 17:21) [17]
> >>default ©  (14.04.04 17:19) [16]
>
> Можно в носу опасной бритвой ковыряться. Ну и что?


Ответ настоящего светлого!!! :))))))

Согласен с VMcL - опасно это. Лучше так не делать.

Да и вообще какое это имеет отношение к вопросу автора.


 
default ©   (2004-04-14 17:23) [19]

VMcL ©   (14.04.04 17:21) [17]
я ничего не навязываю)это было пояснение к возмущению


 
default ©   (2004-04-14 17:25) [20]

пугливые однако)


 
REA ©   (2004-04-14 17:35) [21]

2ЮЗотов:
>Что же еще нужно-то?
Нужно как раз не ClassName, а другой метод. Это я для примера его употребил.

2default> Да так и делал - выдает AV


 
Тимохов ©   (2004-04-14 17:36) [22]


> я для примера его употребил.

плохой значит пример...

Все-таки ваша задача не ясна до конца (прочел весь топик).
Можете по пунктам расписать, что нужно?


 
VMcL ©   (2004-04-14 17:38) [23]

>>default ©  (14.04.04 17:25) [20]

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


 
Юрий Зотов ©   (2004-04-14 17:38) [24]

> REA ©   (14.04.04 17:35) [21]

Чем конкретно не устраивает ClassName?


 
default ©   (2004-04-14 17:41) [25]

REA ©   (14.04.04 17:35) [21]
именно в моём коде? модель вызова register?
VMcL ©   (14.04.04 17:38) [23]
согласен, я бы тоже так вряд ли стал делать в реальном проекте...только если бы скорость ОЧЕНЬ важна была


 
REA ©   (2004-04-14 17:44) [26]

По пунктам (вкратце):
Делаю некий дизайнер форм.
Нужно, чтобы в список доступных объектов добавлялись не TPanel, например, а "Панель".
Для этого допустим написал:

TMyPanel = Class(TPanel)
Published
 Class Function FriendlyComponentName: String;
End;

У меня есть список TClassList с этими объектами. Нужно получить их названия. Типа такого:

If HaveFriendlyName(List[i]) Then MyName := GetName(List[i]);


 
REA ©   (2004-04-14 17:45) [27]

>модель вызова register?
Специально не указывал.


 
VMcL ©   (2004-04-14 17:47) [28]

>>REA ©  (14.04.04 17:45) [27]

В D по дефолту register.


 
Тимохов ©   (2004-04-14 17:50) [29]


> REA ©

Понял, т.е. вы хотите сделать published но только для классовых методов. И именно поэтому не хотите создавать объекты.

Предложение: сделайте таблицу пар соответствия

record
  ClassName: String;
  FriendClassName: String;
end;

занесите тутда

"TPanel", "Панель"
"TForm", "Форма"
и т.д.

потом берете List[i].classname, находите полученную строку в указанной выше таблице, выводите дружественное имя.

вполне нормальное решение.

уверен, что есть и другие (именно как вы хотите).

може же точно рабочее и простое.


 
Тимохов ©   (2004-04-14 17:51) [30]

дополение: тогда естествено придется делать регистрацию всех возможных классов.


 
REA ©   (2004-04-14 17:51) [31]

У меня функция, так что трюки с регистрами может и не пройдут.


 
REA ©   (2004-04-14 17:53) [32]

>Предложение: сделайте таблицу пар соответствия

Усложним задачу - компонеты лежат в динамически подгружаемых BPL.
Если не найду решения, я конечно все в базу затолкаю: имя класса, название, модуль и т.п.


 
default ©   (2004-04-14 17:54) [33]


TMyObj = class
 published
  class procedure PutHello(Param: Byte);
 end;

 TMyMeth = procedure (Param: Byte) of object;

var
 Form1: TForm1;
 M: TMyMeth;

implementation

{$R *.dfm}

class procedure TMyObj.PutHello(Param: Byte);
begin
Form1.Caption := ClassName + " " + IntToStr(Param)
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
TMethod(M).Code := TMyObj.MethodAddress("PutHello");
TMethod(M).Data := TMyObj;
M(20)
end;


вот так похорошему...


 
Юрий Зотов ©   (2004-04-14 21:04) [34]

> REA ©   (14.04.04 17:44) [26]

Сравните исходный вопрос и то, как Вы изложили его же в [26]. Просто, ясно, без всяких шибкоумных "интерфейсов". Есть разница, не правда ли?

Результат - [33]. Оказывается, все, что Вам, было нужно - это показать, как вызывается классовый метод через MethodAddress.

И если бы Вы сразу задали вопрос так, как в [26], то, вне всяких сомнений, тут же получили бы ответ. На чем проблема и была бы закрыта.

Неужели непонятно, что, формулируя вопрос, нужно думать не о том, как сделать его (и себя) "красивым", а о том, как изложить его максимально просто и понятно для всех?


 
REA ©   (2004-04-15 10:08) [35]

Во-первых возможных решений проблемы мне виделось 2 (в т.ч. с "шибкоумным" интерфейсом, который все-равно присутствует для других целей), а на самом деле их может быть и больше. Во-вторых [33] возможно корректен с точки зрения вызова, но не слишком корректен с точки зрения совместимости - решение использует не синтаксические конструкции языка, а информацию о типах, использованных в данной реализации.
Согласен - исходный вопрос был не слишком связен, но с учетом [2] уже достаточно понятен. Понимаю Ваше стремление к чистоте форума, но конструктивно пока получено решение от default, за что ему и спасибо. Сейчас попробую.


 
Тимохов ©   (2004-04-15 10:22) [36]


> REA ©   (15.04.04 10:08) [35]


> конструктивно пока получено решение от default, за что ему
> и спасибо

Давайте вы не будете решать, что конструктивно, а что нет.
Вам дано несколько рабочих решений.
Решайте, лучше, что подходит под ваш "шибкоумный" и непонятный исходный вопрос.


 
REA ©   (2004-04-15 10:29) [37]

Ok, спасибо всем.


 
Юрий Зотов ©   (2004-04-15 10:49) [38]

> REA ©   (15.04.04 10:08) [35]

1. Дело Ваше, можете не делать никаких выводов. Но тогда не удивляйтесь, если в дальнейшем ситуация повторится и в результате долгих коллективных мучений (Ваших, в том числе) Вы получите ответ через сутки, хотя могли бы получить его без проблем и за 5 минут.

2. С чем там несовместимо [33] и почему оно некорректно - кому как, а лично  мне это непонятно. А пробовать тут даже и нечего, это решение проверено уже тысячи раз и работает железно (да и чего бы ему не работать, когда оно сделано по полной "науке"). Осталось только оформить его в виде вот такой функции:
function GetFriendlyName(AClass: TClass): string;
в которую передается ЛЮБОЙ класс, а на выходе - либо Ваше FriendlyName, либо пустая строка (если метод не найден).



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.05.02;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.55 MB
Время: 0.032 c
14-1081390448
lokid7
2004-04-08 06:14
2004.05.02
Библиотека


14-1081276091
Soft
2004-04-06 22:28
2004.05.02
Зачем нужно программирование?


14-1081230936
Sergey13
2004-04-06 09:55
2004.05.02
ГМ продукты. Есть или не есть (в смысле кушать)?


14-1081594606
Makhanev A.S.
2004-04-10 14:56
2004.05.02
WinXP: проблема с навигацией по LAN


1-1081941527
Volodya_
2004-04-14 15:18
2004.05.02
Консоль





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский