zoukankan      html  css  js  c++  java
  • 面向对象: 接口与对象生存周期,接口自动释放

    相关资料:

    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.
    View Code

    调用单元(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.
    View Code

     之前遇到过的一段代码没有理解意思,留下来方便以后学习:

     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}
    View Code
  • 相关阅读:
    convert image to base64 and post to RESTful wcf
    在android webview实现截屏的手动tounchmove裁剪图片
    How to use jquery ajax and android request security RESTful WCF
    using swfUpload in asp.net mvc
    using HttpClient and sending json data to RESTful server in adroind
    ODP.NET数据访问
    android image watermark
    解决国内不能访问github的问题
    idapro权威指南第二版阅读笔记第九章 交叉引用和绘图功能
    idapro权威指南第二版阅读笔记第二章 逆向和反汇编工具
  • 原文地址:https://www.cnblogs.com/FKdelphi/p/12612159.html
Copyright © 2011-2022 走看看