相关资料:
https://www.baidu.com/link?url=yYEHJesIUg6HguekaIW-U0HtjtLn430Dh0NXSc7ej5ixppqcq21rsYMvlCo_qNOP&wd=&eqid=87bf080a00000c50000000035e83f9e4
实例:
接口单元(UnInterface.pas):
1 unit UnInterface; 2 3 interface 4 uses 5 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 6 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ToolWin, Vcl.ActnMan; 7 8 type 9 IFormInterface = interface(IInterface) 10 ['{51869234-9F24-4409-A61D-C6A1A47E7E53}'] 11 procedure ShowForm stdcall; 12 procedure HideForm stdcall; 13 end; 14 15 TFormInterface = class(TForm, IInterface, IFormInterface) 16 // TFormInterface = class(TForm, IFormInterface) 17 private 18 { Private declarations } 19 protected FRefCount: Integer; 20 function QueryInterface(const IID: TGUID; out Obj): HResult; override; stdcall; 21 function _AddRef: Integer stdcall; 22 function _Release: Integer stdcall; 23 procedure ShowForm stdcall; 24 procedure HideForm stdcall; 25 public 26 constructor Create(AOwner: TComponent); override; 27 28 procedure AfterConstruction; override; 29 procedure BeforeDestruction; override; 30 class function NewInstance: TObject; override; 31 property RefCount: Integer read FRefCount; 32 end; 33 34 implementation 35 36 37 procedure TFormInterface.AfterConstruction; 38 begin 39 InterlockedDecrement(FRefCount); 40 end; 41 42 procedure TFormInterface.BeforeDestruction; 43 begin 44 if RefCount <> 0 then 45 raise EInvalidPointer.Create('Invalid ptr'); 46 end; 47 48 constructor TFormInterface.Create(AOwner: TComponent); 49 begin 50 inherited CreateNew(AOwner); 51 end; 52 53 function TFormInterface._AddRef: Integer; 54 begin 55 Result := InterlockedIncrement(FRefCount); 56 end; 57 58 function TFormInterface._Release: Integer; 59 begin 60 Result := InterlockedDecrement(FRefCount); 61 if Result = 0 then 62 Destroy; 63 end; 64 65 class function TFormInterface.NewInstance: TObject; 66 begin 67 Result := inherited NewInstance; 68 TFormInterface(Result).FRefCount := 1; 69 end; 70 71 function TFormInterface.QueryInterface(const IID: TGUID; out Obj): HResult; 72 begin 73 if GetInterface(IID, Obj) then 74 Result := 0 75 else 76 Result := E_NOINTERFACE; 77 end; 78 79 procedure TFormInterface.HideForm; 80 begin 81 Hide; 82 end; 83 84 procedure TFormInterface.ShowForm; 85 begin 86 Show; 87 end; 88 89 end.
调用单元(Unit1.pas):
1 unit Unit1; 2 3 interface 4 5 uses 6 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 7 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ToolWin, Vcl.ActnMan, 8 IdGlobal, 9 UnShare, 10 UnInterface; 11 12 type 13 TForm1 = class(TForm) 14 Button1: TButton; 15 procedure Button1Click(Sender: TObject); 16 private 17 { Private declarations } 18 FIForm: IFormInterface; 19 public 20 { Public declarations } 21 end; 22 23 var 24 Form1: TForm1; 25 26 implementation 27 {$R *.dfm} 28 29 procedure TForm1.Button1Click(Sender: TObject); 30 var 31 iForm: IFormInterface; 32 begin 33 // 运行程序,按下Button1,会看到一个窗体出现,2秒钟后它消失了,这就实现了自动释放的功能 34 // iForm := TFormInterface.Create(nil) as IFormInterface; 35 // iForm.ShowForm; 36 // Sleep(2000); 37 // 在Form1中定义一个成员变量,是一个IFormInterface型的接口,则对象能保持到程序退出时,Form1被释放时自动释放 38 // 写成TFormInterface.Create(Self)的话会出现释放的问题 39 iForm := TFormInterface.Create(nil) as IFormInterface; 40 iForm.ShowForm; 41 FIForm := iForm; 42 end; 43 end.
之前遇到过的一段代码没有理解意思,留下来方便以后学习:
1 //功能: 直接解读对象内存结构,返回自身实现的对象 2 //参数: 3 //注意:对 x64 的修改,参考 https://forums.embarcadero.com/thread.jspa?threadID=62328 4 //////////////////////////////////////////////////////////////////////////////// 5 function GetImplObject(const AIntf: IInterface): TObject; 6 {$IFDEF CPUX64} 7 begin 8 try 9 Result := AIntf as TObject; 10 except 11 Result := nil; 12 end; 13 end; 14 {$ELSE} 15 const 16 AddByte = $04244483; // opcode for ADD DWORD PTR [ESP+4], Shortint 17 AddLong = $04244481; // opcode for ADD DWORD PTR [ESP+4], Longint 18 type 19 PAdjustSelfThunk = ^TAdjustSelfThunk; 20 TAdjustSelfThunk = packed record 21 case AddInstruction: Longint of 22 AddByte: (AdjustmentByte: ShortInt); 23 AddLong: (AdjustmentLong: Longint); 24 end; 25 PInterfaceMT = ^TInterfaceMT; 26 TInterfaceMT = packed record 27 QueryInterfaceThunk: PAdjustSelfThunk; 28 end; 29 TInterfaceRef = ^PInterfaceMT; 30 var 31 QueryInterfaceThunk: PAdjustSelfThunk; 32 begin 33 try 34 Result := Pointer(AIntf); 35 if Assigned(Result) then 36 begin 37 QueryInterfaceThunk := TInterfaceRef(AIntf)^.QueryInterfaceThunk; 38 case QueryInterfaceThunk.AddInstruction of 39 AddByte: 40 Inc(PAnsiChar(Result), QueryInterfaceThunk.AdjustmentByte); 41 AddLong: 42 Inc(PAnsiChar(Result), QueryInterfaceThunk.AdjustmentLong); 43 else 44 Result := nil; 45 end; 46 end; 47 except 48 Result := nil; 49 end; 50 end; 51 {$ENDIF}