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

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

Попытка доступа к методам класса [D7, Win2k]


Страницы:   1 2

Юрий_К ©   (2007-01-11 19:28:00) 

http://www.clubdelphi.com/foros/archive/index.php/t-32526.html
Нашёл в сети код (линк дал выше) :

unit PubMeth;
interface
uses
Classes, TypInfo;
type
PVmtMethod = ^TVmtMethod;
TVmtMethod = packed record
Size: Word;
Address: Pointer;
Name: ShortString;
end;
PVmtMethodTable = ^TVmtMethodTable;
TVmtMethodTable = packed record
Count: Word;
Methods: array [0..MaxListSize] of byte;
{ Methods : array [0..Count] of TVmtMethod;}
end;
TPublishedMethodIterator = class
private
FVMT: Pointer;
FMethodTable: PVmtMethodTable;
FCurrent: PVmtMethod;
FCurrentIndex: Integer;
function CurrentLength: Integer;
public
property VMT: Pointer read FVMT;
property Current: PVmtMethod read FCurrent;
function GetMethodCount: Integer;
procedure Init(AClass: TClass);
function First: PVmtMethod;
function Next: PVmtMethod;
end;
function OffsetPtr(P: Pointer; Offset: Integer): Pointer;
implementation
function OffsetPtr(P: Pointer; Offset: Integer): Pointer;
begin
Integer(Result) := Integer(P) + OffSet;
end;
{ TPublishedMethodIterator }
function TPublishedMethodIterator.GetMethodCount: Integer;
begin
Result := 0;
if not Assigned(FMethodTable) then Exit;
Result := FMethodTable^.Count;
end;
procedure TPublishedMethodIterator.Init(AClass: TClass);
begin
FMethodTable := nil;
FVMT := Pointer(AClass);
FMethodTable := Pointer( OffsetPtr(FVMT, vmtMethodTable)^ );
FCurrent := nil;
end;
function TPublishedMethodIterator.First: PVmtMethod;
begin
Result := nil;
FCurrentIndex := 0;
if not Assigned(FMethodTable) then Exit;
FCurrent := Pointer(@FMethodTable.Methods[0]);
Result := FCurrent;
end;
function TPublishedMethodIterator.CurrentLength: Integer;
begin
Result := 0;
if not Assigned(FCurrent) then Exit;
Result := Current^.Size; // SizeOf(Word) + SizeOf(Pointer) + Length(Current^.Name) + 1;
end;
function TPublishedMethodIterator.Next: PVmtMethod;
begin
Result := nil;
if not Assigned(FMethodTable) then Exit;
if FCurrentIndex + 1 >= GetMethodCount then
begin
FCurrent := nil;
end
else
begin
FCurrent := OffsetPtr(FCurrent, CurrentLength);
Inc(FCurrentIndex);
end;
Result := FCurrent;
end;
end.

Использовал так:

procedure TForm1.Button1Click(Sender: TObject);
var
MethodIterator: TPublishedMethodIterator;
Cls: TClass;
begin
re2.Clear;
MethodIterator := TPublishedMethodIterator.Create;
Cls := Sender.ClassType;
try
with MethodIterator do
begin
while Cls <> nil do
begin
Init(Cls);
re2.Lines.Add(Format('%s, %d methods',[TClass(VMT).ClassName, GetMethodCount]));
First;
while (Current <> nil) do
begin
re2.Lines.Add(Format(' %s: $%p',[Current^.Name, Current^.Address]));
Next;
end;
Cls := Cls.ClassParent;
end;
end;
finally
MethodIterator.Free;
end;

Что получил:
"
TButton, 0 methods
TButtonControl, 0 methods
TWinControl, 0 methods
TControl, 0 methods
TComponent, 0 methods
TPersistent, 0 methods
TObject, 0 methods
"
Что же, у всех этих классов кол-во публичных методов равно нулю?
Или что-то тут не так?


Бурундук   (2007-01-12 11:50:00) [21]

2Юрий_К   (12.01.07 11:40) [9]

>Использование кода было в
>"procedure TForm1.Button1Click(Sender: TObject);".
>Почему хотя бы этот Button1Click в таком случае не посчитался?
>Может он динамический?

Какая разница, откуда ты вызвал код?
Чтобы увидеть Button1Click, тебе нужно смотреть
опубликованные методы класса TForm1,
а ты смотрел методы класса TButton.

Если хочешь увидеть Button1Click, поменяй
 Cls := Sender.ClassType;
на
 Cls := Self.ClassType;


Юрий_К   (2007-01-12 11:43:00) [22]

Не совсем полностью скопировал выше:
"
VMT=0042348C
 Destroy=00412D70
 FreeInstance=004029B8
 NewInstance=00402990
 DefaultHandler=00413EF0
 InstanceSize=264
 ClassParent=TButtonControl (004233D8)
 ClassName=TButton
 ClassInfo=00423568
 DynMethodTable=00423540
   Count: 5
   Dyn Method 0=00425DB8 (B005)
   Dyn Method 1=00425E20 (B006)
   Dyn Method 2=00425EA0 (B007)
   Dyn Method 3=00425DA4 (BD11)
   Dyn Method 4=00425CA8 (-11)
 MethodTable=00000000
 FieldTable=00000000
 InitTable=00000000
 AutoTable=00000000
"


Юрий_К   (2007-01-12 11:40:00) [23]

Бурундук ©   (11.01.07 22:37) [2]
"Разумеется, равно нулю.
Публичные методы используются в основном для обработчиков событий,
всяких Form1Create, Button1Click и т.п."

Использование кода было в "procedure TForm1.Button1Click(Sender: TObject);".
Почему хотя бы этот Button1Click в таком случае не посчитался? Может он динамический?

VMTDemo (Delphi2) от Рэя Лишнера даёт
"
VMT=0042348C
 Destroy=00412D70
 FreeInstance=004029B8
 NewInstance=00402990
 DefaultHandler=00413EF0
 InstanceSize=264
 ClassParent=TButtonControl (004233D8)
 ClassName=TButton
 ClassInfo=00423568
 DynMethodTable=00423540
   Count: 5
   Dyn Method 0=00425DB8 (B005)
   Dyn Method 1=00425E20 (B006)
   Dyn Method 2=00425EA0 (B007)
"

procedure WriteVmtInfo(ClassType: TClass);
var
 Vmt: PVmt;
begin
 Vmt := PVmt(ClassType);
 Dec(Vmt, 1);
 FmtLn('VMT=%p', [Vmt]);
 FmtLn('  Destroy=%p', [Vmt^.Destroy]);
 FmtLn('  FreeInstance=%p', [Vmt^.FreeInstance]);
 FmtLn('  NewInstance=%p', [Vmt^.NewInstance]);
 FmtLn('  DefaultHandler=%p', [Vmt^.DefaultHandler]);
 FmtLn('  InstanceSize=%d', [Vmt^.InstanceSize]);
 if Vmt^.ClassParent = nil then
   WriteLn('  ClassParent=nil')
 else
   FmtLn('  ClassParent=%s (%p)', [Vmt^.ClassParent.ClassName, Pointer(Vmt^.ClassParent)]);
 WriteLn('  ClassName=', GetClassName(Vmt)^);

{$ifdef WIN32}
 FmtLn('  ClassInfo=%p', [Vmt^.TypeInfo]);
{$else}
 FmtLn('  ClassInfo=%x', [Vmt^.TypeInfo]);
{$endif}

{$ifdef WIN32}
 FmtLn('  DynMethodTable=%p', [Vmt^.DynMethodTable]);
{$else}
 FmtLn('  DynMethodTable=%x', [Vmt^.DynMethodTable]);
{$endif}
if Vmt^.DynMethodTable <> VmtNil then
 WriteDynMethods(Vmt);

{$ifdef WIN32}
 FmtLn('  MethodTable=%p', [Vmt^.MethodTable]);
{$else}
 FmtLn('  MethodTable=%x', [Vmt^.MethodTable]);
{$endif}
 if Vmt^.MethodTable <> VmtNil then
   WriteMethods(GetMethodTable(Vmt));

{$ifdef WIN32}
 FmtLn('  FieldTable=%p', [Vmt^.FieldTable]);
{$else}
 FmtLn('  FieldTable=%x', [Vmt^.FieldTable]);
{$endif}
 if Vmt^.FieldTable <> VmtNil then
   WriteFields(GetFieldTable(Vmt));

{$ifndef VER80}
 FmtLn('  InitTable=%p', [Vmt^.InitTable]);
 if Vmt^.InitTable <> nil then
   WriteInitTable(GetInitTable(Vmt));

 FmtLn('  AutoTable=%p', [Vmt^.AutoTable]);
 if Vmt^.AutoTable <> nil then
   WriteAutoTable(GetAutoTable(Vmt));
{$endif}
end;


Джо   (2007-01-12 10:16:00) [24]

> Бурундук

Гм. И автор вопрос тоже «описался»? Или «был введен в заблуждение»? Желательно было бы определиться и автору вопроса и автору кода :)


Бурундук   (2007-01-12 10:15:00) [25]

Вы слушайте, что я имею ввиду, а не то, что я говорю!
(с) Фейнман


Бурундук   (2007-01-12 10:05:00) [26]

Джо ©   (12.01.07 05:44) [5]
описался, блин. Опубликованных, конечно.


Джо   (2007-01-12 05:44:00) [27]

> [2] Бурундук ©   (11.01.07 22:37)
> Юрий_К   (11.01.07 19:28)  
> Что же, у всех этих классов кол-во публичных методов равно
> нулю?
>
> Разумеется, равно нулю.

 TButton = class(TButtonControl)
  public
   constructor Create(AOwner: TComponent); override;
   procedure Click; override;
   function UseRightToLeftAlignment: Boolean; override;
 end;
Не считая предков, там вообще море.


Anatoly Podgoretsky   (2007-01-12 02:16:00) [28]

> GrayFace  (12.01.2007 02:14:03)  [3]

Зато published так не переводится.


GrayFace   (2007-01-12 02:14:00) [29]

Точнее, нет published методов. Public тоже переводится как публичный.


Бурундук   (2007-01-11 22:37:00) [30]

Юрий_К   (11.01.07 19:28)  
Что же, у всех этих классов кол-во публичных методов равно нулю?

Разумеется, равно нулю.
Публичные методы используются в основном для обработчиков событий,
всяких Form1Create, Button1Click и т.п.

PS код, кстати, мой.


vlad-mal   (2007-01-11 20:12:00) [31]


> http://www.clubdelphi.com/foros/archive/index.php/t-32526.
> htmlНашёл в сети код (линк дал выше) :


Обрати внимание на это:
En el artículo Run-Time Type Information (RTTI) in Delphi ( http://www.blong.com/Conferences/BorConUK98/DelphiRTTI/CB140.htm), de Brian Long ( http://www.blong.com/), se explica bastante bien cómo puede obtenerse información sobre tipos en tiempo de ejecución. No os perdáis el resto de documentación disponible en la página Web de Brian Long.


Страницы:   1 2

Наверх

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