惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Security Archives - TechRepublic
MongoDB | Blog
MongoDB | Blog
量子位
博客园 - 叶小钗
罗磊的独立博客
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News: Ask HN
Hacker News: Ask HN
MyScale Blog
MyScale Blog
GbyAI
GbyAI
Help Net Security
Help Net Security
Y
Y Combinator Blog
Engineering at Meta
Engineering at Meta
Hacker News - Newest:
Hacker News - Newest: "LLM"
Latest news
Latest news
H
Hacker News: Front Page
Blog — PlanetScale
Blog — PlanetScale
雷峰网
雷峰网
Microsoft Azure Blog
Microsoft Azure Blog
P
Proofpoint News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
Scott Helme
Scott Helme
S
Schneier on Security
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
S
Security @ Cisco Blogs
Recorded Future
Recorded Future
S
Securelist
博客园 - Franky
Application and Cybersecurity Blog
Application and Cybersecurity Blog
A
About on SuperTechFans
N
News and Events Feed by Topic
AI
AI
T
Tenable Blog
N
News | PayPal Newsroom
C
Cybersecurity and Infrastructure Security Agency CISA
V
V2EX - 技术
T
Threat Research - Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
L
LINUX DO - 热门话题
N
Netflix TechBlog - Medium
S
SegmentFault 最新的问题
T
The Blog of Author Tim Ferriss
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Google Online Security Blog
Google Online Security Blog
S
Security Affairs
Webroot Blog
Webroot Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园 - 三生石上(FineUI控件)
C
Comments on: Blog
G
GRAHAM CLULEY

博客园 - 左左右右

连接 password ttreeview 一些汇编指令 Delphi与汇编 TObject.Dispatch TApplication与主消息循环 核心库类之TGraphicControl/TcustomControl 与画布(Canvas) 核心库类之TControl 内存管理 触发器 模式窗体和非模式窗体 在dll中delphi中封装窗体(实例) MessageDlg dll 杂题 Delphi异常 Delphi与C++的语法区别 消息自定义
核心库类之TObject
左左右右 · 2007-05-08 · via 博客园 - 左左右右

 1TObject = class
 2    constructor Create;
 3    procedure Free;
 4    class function InitInstance(Instance: Pointer): TObject;
 5    procedure CleanupInstance;
 6    function ClassType: TClass;
 7    class function ClassName: ShortString;
 8    class function ClassNameIs(const Name: string): Boolean;
 9    class function ClassParent: TClass;
10    class function ClassInfo: Pointer;
11    class function InstanceSize: Longint;
12    class function InheritsFrom(AClass: TClass): Boolean;
13    class function MethodAddress(const Name: ShortString): Pointer;
14    class function MethodName(Address: Pointer): ShortString;
15    function FieldAddress(const Name: ShortString): Pointer;
16    function GetInterface(const IID: TGUID; out Obj): Boolean;
17    class function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry;
18    class function GetInterfaceTable: PInterfaceTable;
19    function SafeCallException(ExceptObject: TObject;
20      ExceptAddr: Pointer): HResult; virtual;
21    procedure AfterConstruction; virtual;
22    procedure BeforeDestruction; virtual;
23    procedure Dispatch(var Message); virtual;
24    procedure DefaultHandler(var Message); virtual;
25    class function NewInstance: TObject; virtual;
26    procedure FreeInstance; virtual;
27    destructor Destroy; virtual;
28  end;
29

提供的对象服务:
对象创建服务、对象释放服务、对象识别服务、对象信息服务、对象消息分派服务。
1.对象创建服务
   除了TObjiect的构造函数之外的其他相关函数如下:

TObject = class
    constructor Create;
    class 
function InitInstance(Instance: Pointer): TObject;
    class 
function InstanceSize: Longint;
    procedure AfterConstruction; virtual;
    class 
function NewInstance: TObject; virtual;
    destructor Destroy; virtual;
  
end;

TObject的NewInstance是虚拟方法,代表派生类可以改写(override)它。NewInstance的功能即是为对象分配内存,并调用InitInstance方法为对象设定对象支持的接口。NewInstance的返回值是TObject,代表了调用了NewInstance之后Object Pascal的对象模型已经在内存中形成了TObject的实体(instance),不过此时内存中的TObject仍然无法使用,因为接着需要设定对象的执行框架。

2.对象识别服务
  TObject提供的基础识别对象方法:

TObjiect = class
       class 
function ClassName: ShortString;
    class 
function ClassNameIs(const Name: string): Boolean;
    class 
function ClassParent: TClass;
    class 
function InstanceSize: Longint;
    class 
function InheritsFrom(AClass: TClass): Boolean;
end;

用来得知应用程序执行时期对象的信息。这些对象识别服务方法都是声明成类方法。识别服务方法说明:
 ClassName 返回类名称
 ClassNameIs  返回特定类的名称
 ClassParent     返回类的父类
  InstanceSize  返回对象占据内存的大小
  InheritsFrom 判断类是否从特定类继承下来
 
3 .对象信息服务
  相关函数:

TObject = class
    class 
function ClassInfo: Pointer;
    class 
function MethodAddress(const Name: ShortString): Pointer;
    class 
function MethodName(Address: Pointer): ShortString;
    
function FieldAddress(const Name: ShortString): Pointer;
    
function GetInterface(const IID: TGUID; out Obj): Boolean;
    class 
function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry;
    class 
function GetInterfaceTable: PInterfaceTable;
    
function SafeCallException(ExceptObject: TObject;
      ExceptAddr: Pointer): HResult; virtual;
end;

4.对象释放服务
  相关函数:

TObject = class
    procedure Free;
    procedure CleanupInstance;
    procedure FreeInstance; virtual;
    destructor Destroy; virtual;
end;

destructor TObject.Destroy;
begin
end;

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;
procedure TObject.FreeInstance;
begin
  CleanupInstance;
  _FreeMem(Self);
end;
procedure TObject.CleanupInstance;
{$IFDEF PUREPASCAL}
var
  ClassPtr: TClass;
  InitTable: Pointer;
begin
  ClassPtr := ClassType;
  InitTable := PPointer(Integer(ClassPtr) + vmtInitTable)^;
  while (ClassPtr <> nil) and (InitTable <> nil) do
  begin
    _FinalizeRecord(Self, InitTable);
    ClassPtr := ClassPtr.ClassParent;
    if ClassPtr <> nil then
      InitTable := PPointer(Integer(ClassPtr) + vmtInitTable)^;
  end;
end;

4.分派消息服务
   在TObject类中,有一个Dispatch()方法和一个DefaultHandler()方法,它们都是与消息分发机制相关的。

TObject = class
    procedure Dispatch(var Message); virtual;
    procedure DefaultHandler(var Message); virtual;
end;

Dispatch和DefaultHandler使用了未指明类型的参数Message,他们可以接受任何数据类型的参数,唯一要求这个数据类型的前两个字节必须是消息ID值,Dispatch和DefaultHandler会根据这个消息ID搜寻拥有相同消息ID的方法,然后把这个参数分配给搜寻到的方法。
    Dispatch()负责将特定的消息分发给合适的消息处理函数。首先它会在对象本身类型的类中寻找该消息的处理函数,如果找到,则调用它;如果没有找到而该类覆盖了TObject的DefaultHandler(),则调用该类的DefaultHandler();如果两者都不存在,则继续在其基类中寻找,直至寻找到TObject这一层,而TObject已经提供了默认的DefaultHandler()方法。
procedure TObject.Dispatch(var Message);
asm
    PUSH    ESI
    MOV     SI,[EDX]
    OR      SI,SI
   //比对ID处理的范围,如果不在0~c000h之间就跳到 @@default处调
   //用 DefaultHandler函数处理
    JE      @@default
    CMP     SI,0C000H
    JAE     @@default
    PUSH    EAX
    MOV     EAX,[EAX]
    //在VCL组件的动态方法表格中搜寻可处理的事件函数
    CALL    GetDynaMethod
    POP     EAX
    JE      @@default
    MOV     ECX,ESI
    POP     ESI
    //找到能够处理消息的VCL事件处理函数,直接跳到此事件处理函数执行
    JMP     ECX

@@default:
    POP     ESI
    MOV     ECX,[EAX]
    JMP     dword ptr [ECX].vmtDefaultHandler
end;
procedure TObject.DefaultHandler(var Message);
begin
end;