Форум: "Основная";
Текущий архив: 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.038 c