Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Определение адреса конструктора [D6, Win95/98, WinME, NT4, Win2k, WinXP]


Страницы:   1 2 3

Ученик ©   (2002-07-16 16:13:00) 

Можно по адресу класса определить адрес конструктора объектов этого класса ?

var
P : Pointer;
begin
P := TBitmap;

Необходимо вычислить адрес TBitmap.Create, используя P, возможно ли ?


Digitman   (2002-07-17 14:32:00) [1]

>Ученик

За меня не волнуйся)
Мне совершенно по-барабану беспредметный треп постороннего.

Вот гораздо важнее, что ты скажешь по теме ...
Но ты-таки решил закрыть тему, не доведя ее до истины ... И совершенно напрасно ...


Skier   (2002-07-17 13:23:00) [2]

Ребята, завязывайте...


Ученик   (2002-07-17 13:22:00) [3]

>Уролог
Вы сейчас полностью дискредитировали уважаемого Digitman.


Уролог   (2002-07-17 13:10:00) [4]

Господа ! Сдается мне, старому специалисту, что у Digitman © потолще и подлиннее, чем у Ученик. И есть подспудная мысль, что Ученик"а мучает юношеский максимализм. Но это уже к другому специалисту.


Ученик   (2002-07-17 13:04:00) [5]

>Digitman
)


Digitman   (2002-07-17 13:00:00) [6]

>Ученик
Да как тебе будет угодно, сударь)


Ученик   (2002-07-17 12:52:00) [7]

>Digitman
Без комментариев


Digitman   (2002-07-17 12:48:00) [8]

>Ученик

Так вот если "сам не знаю что хочу" - разберись для начала, а потом уже упрекай стремящихся помочь тебе в невнимательности. С аргументами серьезными, а не словоблудием !


Ученик   (2002-07-17 12:44:00) [9]

>Digitman
Если Вам будет легче, то каюсь, я сам не знаю что хочу, задаю дурацкие вопросы и не прислушиваюсь к ответам великих мастеров Delphi, надеюсь мы не будем продолжать, кто-то должен оказаться умнее.


Digitman   (2002-07-17 12:40:00) [10]

>Ученик

Чушь. В данном случае именно ты невнимателен.

Цитирую тебя :

(1)
>>Необходимо вычислить адрес TBitmap.Create, используя P, >>возможно ли ?

(2)
>>Вызывается конструктор TObject


Вот - еще раз - код, отвечающий на твой вопрос (1) и опровергающий твое утверждение (2)

Тот самый твой TBitmap - не имеющий к TComponent отношения.


procedure TfMain.ButtonXClick(Sender: TObject);
var
var
p: procedure;
c: TClass;
t: TObject;
begin
p:= @TComponent.Create; // вот тебе адрес
RegisterClass(TBitmap);
c:= GetClass("TBitmap");
asm
mov dl,1
mov eax, [c]
call dword ptr [p] // вот тебе создание объекта TBitmap
mov [t], eax
end;

t.free; // вот тебе разрушение созданного объекта TBitmap

end;


Отрассируй и убедись сам !!!


Ученик   (2002-07-17 12:03:00) [11]

>Digitman
Внимательности, внимательности и еще раз внимательности, прочитайте еще раз эту страницу.


Digitman   (2002-07-17 11:56:00) [12]

>Ученик

Я вот не вижу, что ты "остановился" ...
Так ты до сих пор и не смог вразумительно объяснить суть проблемы...

Тебе ж сказали уже - в любом случае нужно заранее знать класс зарегистрированного объекта, иметь ссылку на дескриптор класса и иметь декларацию его конструктора . Только тогда с помощью VMT можно вызывать конструирующие методы класса с приведенными выше оговорками.


Ученик   (2002-07-17 11:26:00) [13]

>Digitman
>И я об этом говорю, только вот он никак это , видимо, не >уразумеет.

Я уже давно остановился Ученик (16.07.02 19:36)

>TComponent - прямой наследник TPersistent, и непонятно в таком >случае, какие у тебя сложности, если ты говоришь, что >конструируешь любого наследника TComponent без проблем.

Внимательности вам не хватает мастера (Digitman, Юрий Зотов), внимательности, а так цены бы вам не было ))), так много и хорошо пишете про простые вещи.





Digitman   (2002-07-17 11:16:00) [14]

>vuk
>>Автору вопроса в решении его задачи это ни коим образом не поможет

Разумеется, не поможет ! И я об этом говорю, только вот он никак это , видимо, не уразумеет.

А все то, что я , как ты говоришь, "сложно" изложил - лишь в стремлении именно наглядно показать, что адрес корректно определяется и явный вызов констр.метода по полученному адресу вполне возможен, но сопряжен с вышеописанными проблемами.

>Ученик

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


vuk   (2002-07-17 10:58:00) [15]

>Здесь есть вот какие тонкости
Я именно об этом. Вообще говоря, можно написать то, что написали Вы несколько проще. Если вспомнить, что конструктор - функция, возвращающая созданный экземпляр, то все просто. Конструктор без параметров можно представить примерно так:

type
TSimpleConstructor = function (ClassRef : TClass) : TObject; register;
соответственно конструктор TComponent будет иметь вид

type
TComponentConstructor = function (ClassRef : TClass; AOwner : TComponent ) : TObject; register;

Тогда вызов делается проще. Предположим, что в вышем примере переменная p имеет тип TComponentConstructor и содержит адрес конструктора, тогда его вызов будет примерно следующим:
asm
mov dl, 1
end;
t := P(c, nil);

Вот только в приведенном Вами примере все это будет лишним, поскольку все то же самое можно сделать проще, поскольку у наследников TComponent есть виртуальный конструктор и все действия, приведенные выше не особо нужны. Автору вопроса в решении его задачи это ни коим образом не поможет, поскольку он не знает, какого класса экземпляры он будет создавать и следовательно не будет иметь возможности получить адрес конкретного конструктора (у Вас это сделано явно в выделенной строке).
А с наследниками TComponent все просто. Предположим, что в переменной A содержится экземпляр какого-то наследника TComponent, тогда:
C := TComponentClass( A.GetClass ).Create( nil );


Ученик   (2002-07-17 10:52:00) [16]

>Игорь Шевченко
Речь шла о конструкторе
>Digitman
У нас проблема с вызовом конструкторов объектов порожденных от TObject и TPersistent, с компонентами проблем нет у них конструктор override; и все вызывается обычным образом
TComponentClass(FindClass("Имя класса")).Create(AOwner)


Digitman   (2002-07-17 10:32:00) [17]

>Ученик

Как это - нет ? Вот же он !

procedure TfMain.ButtonXClick(Sender: TObject);
var
var
p: procedure;
c: TClass;
t: TObject;
begin
p:= @TComponent.Create;
c:= GetClass("TComponent");
asm
mov dl,1 // создавать экземпляр
mov eax, [c] // VMT
mov ecx, 0 // Owner = nil
call dword ptr [p] // собственно - вызов конструктора по адресу
mov [t], eax // результат - ссылка на созданный и иниц-ный экз-р
end;

t.free; // разрушение созданного объекта

end;


Игорь Шевченко   (2002-07-17 10:20:00) [18]

Адрес деструктора прописан в таблице VMT со смещением -4
(vmtDestroy)


Ученик   (2002-07-17 10:10:00) [19]

>Digitman
Если что-то надо, можно и на встроенном ассемблере написать, только вот похоже адреса то нету, в любом случае, спасибо.


Digitman   (2002-07-17 10:02:00) [20]

>vuk

Здесь есть вот какие тонкости :

Если перед вызовом конструирующего метода некоего класса РОН dl = 1, то непосредственно перед инициализацией экземпляра будет вызвана системная процедура ClassCreate, отвечающая за генерацию экземпляра. В противном случае (РОН dl = 0) будет произведена только попытка инициализации, и это приведет к исключению при отсутствии экземпляра.

Все inherited-конструкторы вызываются с dl = 0.

Вызов любого конструирующего метода любого класса всегда предваряется занесением в РОН eax адреса VMT

Кр.того, если конструирующий метод класса имеет параметры, их также нужно передавать : первый параметр (в порядке их перечисления в декларации конструктора) - в РОН ecx, остальные - последовательным занесением в стек.

>Ученик

Всю эту последовательность действий формирует компилятор "прозрачно" для программера.

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


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо