TObject = class
//創(chuàng)建
constructor Create;
//釋放
procedure Free;
//初始化實(shí)列
class function InitInstance(Instance: Pointer): TObject;
//清除實(shí)列
procedure CleanupInstance;
//獲得類的類型
function ClassType: TClass;
//獲得了的名稱
class function ClassName: ShortString;
//判斷類的名稱
class function ClassNameIs(const Name: string): Boolean;
//類的父類
class function ClassParent: TClass;
//類的信息指針
class function ClassInfo: Pointer;
//當(dāng)前類的實(shí)列大小
class function InstanceSize: Longint;
//判斷是否從一個(gè)類繼承下來
class function InheritsFrom(AClass: TClass): Boolean;
//根據(jù)方法的名稱獲得方法的地址
class function MethodAddress(const Name: ShortString): Pointer;
//根據(jù)地址或的方法的名稱
class function MethodName(Address: Pointer): ShortString;
//根據(jù)名稱獲得屬性的地址
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;
//安全調(diào)用例外
function SafeCallException(ExceptObject: TObject;
ExceptAddr: Pointer): HResult; virtual;
//創(chuàng)建之后的執(zhí)行
procedure AfterConstruction; virtual;
//釋放之前的執(zhí)行
procedure BeforeDestruction; virtual;
//分派消息
procedure Dispatch(var Message); virtual;
//默認(rèn)的句柄
procedure DefaultHandler(var Message); virtual;
//新的實(shí)列
class function NewInstance: TObject; virtual;
//釋放實(shí)列
procedure FreeInstance; virtual;
//釋放
destructor Destroy; virtual;
end;
//初始化實(shí)列
class function TObject.InitInstance(Instance: Pointer): TObject;
{$IFDEF PUREPASCAL}
var
IntfTable: PInterfaceTable;
ClassPtr: TClass;
I: Integer;
begin
//分配需要的內(nèi)存的大小
FillChar(Instance^, InstanceSize, 0);
//實(shí)列化分配好的內(nèi)存
PInteger(Instance)^ := Integer(Self);
ClassPtr := Self;
//如果成功
while ClassPtr <> nil do
begin
//獲得接口表
IntfTable := ClassPtr.GetInterfaceTable;
//遍歷接口
if IntfTable <> nil then
for I := 0 to IntfTable.EntryCount-1 do
//初始化每個(gè)接口函數(shù)的具體實(shí)現(xiàn)
with IntfTable.Entries[I] do
begin
if VTable <> nil then
PInteger(@PChar(Instance)[IOffset])^ := Integer(VTable);
end;
ClassPtr := ClassPtr.ClassParent;
end;
Result := Instance;
end;
//清除實(shí)列
procedure TObject.CleanupInstance;
{$IFDEF PUREPASCAL}
var
ClassPtr: TClass;
InitTable: Pointer;
begin
//獲得當(dāng)前的類型
ClassPtr := ClassType;
//獲得初始化標(biāo)的地址
InitTable := PPointer(Integer(ClassPtr) + vmtInitTable)^;
//如果當(dāng)前類存在 并且初始化表也存在
while (ClassPtr <> nil) and (InitTable <> nil) do
begin
//釋放所有的信息
_FinalizeRecord(Self, InitTable);
//如果當(dāng)前類有父類 則清楚父類的信息
ClassPtr := ClassPtr.ClassParent;
if ClassPtr <> nil then
InitTable := PPointer(Integer(ClassPtr) + vmtInitTable)^;
end;
end;
//獲得當(dāng)前類的類型
function TObject.ClassType: TClass;
begin
//就是返回當(dāng)前類的指針
Pointer(Result) := PPointer(Self)^;
end;
//獲得當(dāng)前類的類名
class function TObject.ClassName: ShortString;
{$IFDEF PUREPASCAL}
begin
//根據(jù)虛擬方發(fā)表返回指定的地址
Result := PShortString(PPointer(Integer(Self) + vmtClassName)^)^;
end;
// 判斷當(dāng)前類的類名
class function TObject.ClassNameIs(const Name: string): Boolean;
{$IFDEF PUREPASCAL}
var
Temp: ShortString;
I: Byte;
begin
Result := False;
//獲得當(dāng)前類的類名得指針
Temp := ClassName;
//根據(jù)字符串的長度比較每個(gè)字符 區(qū)分大小寫
for I := 0 to Byte(Temp[0]) do
if Temp[I] <> Name[I] then Exit;
Result := True;
end;
//獲得當(dāng)前類的父類
class function TObject.ClassParent: TClass;
{$IFDEF PUREPASCAL}
begin
//根據(jù)虛擬方法表或的父的地址指針
Pointer(Result) := PPointer(Integer(Self) + vmtParent)^;
//如果存在父類 則返回
if Result <> nil then
Pointer(Result) := PPointer(Result)^;
end;
{$ELSE}
asm
MOV EAX,[EAX].vmtParent
TEST EAX,EAX
JE @@exit
MOV EAX,[EAX]
@@exit:
end;
//獲得類型信息
class function TObject.ClassInfo: Pointer;
begin
Result := PPointer(Integer(Self) + vmtTypeInfo)^;
end;
//獲得實(shí)列大小
class function TObject.InstanceSize: Longint;
begin
Result := PInteger(Integer(Self) + vmtInstanceSize)^;
end;
//判斷是否從一個(gè)類繼承下來
class function TObject.InheritsFrom(AClass: TClass): Boolean;
{$IFDEF PUREPASCAL}
var
ClassPtr: TClass;
begin
ClassPtr := Self;
//當(dāng)前類是否存在 并且和比較的類不等
while (ClassPtr <> nil) and (ClassPtr <> AClass) do
//獲得這個(gè)類的父類
ClassPtr := PPointer(Integer(ClassPtr) + vmtParent)^;
Result := ClassPtr = AClass;
end;
{$ELSE}
asm
{ -> EAX Pointer to our class }
{ EDX Pointer to AClass }
{ <- AL Boolean result }
JMP @@haveVMT
@@loop:
MOV EAX,[EAX]
@@haveVMT:
CMP EAX,EDX
JE @@success
MOV EAX,[EAX].vmtParent
TEST EAX,EAX
JNE @@loop
JMP @@exit
@@success:
MOV AL,1
@@exit:
end;
//根據(jù)方法名稱獲得地址
class function TObject.MethodAddress(const Name: ShortString): Pointer;
asm
{ -> EAX Pointer to class }
{ EDX Pointer to name }
PUSH EBX
PUSH ESI
PUSH EDI
XOR ECX,ECX //清零
XOR EDI,EDI //清零
MOV BL,[EDX] //獲得字符串的長度
JMP @@haveVMT //判斷是否有虛擬方發(fā)表
@@outer: { upper 16 bits of ECX are 0 ! }
MOV EAX,[EAX]
@@haveVMT:
MOV ESI,[EAX].vmtMethodTable //獲得虛擬方發(fā)表的地址
TEST ESI,ESI |