mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 08:28:08 +02:00

the IInterface implementation to be XPCom-compatible --- Merging r15997 through r16179 into '.': U rtl/inc/variants.pp U rtl/inc/objpash.inc U rtl/inc/objpas.inc U rtl/objpas/classes/persist.inc U rtl/objpas/classes/compon.inc U rtl/objpas/classes/classesh.inc A tests/test/tconstref1.pp A tests/test/tconstref2.pp A tests/test/tconstref3.pp U tests/test/tinterface4.pp A tests/test/tconstref4.pp U tests/webtbs/tw10897.pp U tests/webtbs/tw4086.pp U tests/webtbs/tw15363.pp U tests/webtbs/tw2177.pp U tests/webtbs/tw16592.pp U tests/tbs/tb0546.pp U compiler/sparc/cpupara.pas U compiler/i386/cpupara.pas U compiler/pdecsub.pas U compiler/symdef.pas U compiler/powerpc/cpupara.pas U compiler/avr/cpupara.pas U compiler/browcol.pas U compiler/defcmp.pas U compiler/powerpc64/cpupara.pas U compiler/ncgrtti.pas U compiler/x86_64/cpupara.pas U compiler/opttail.pas U compiler/htypechk.pas U compiler/tokens.pas U compiler/objcutil.pas U compiler/ncal.pas U compiler/symtable.pas U compiler/symsym.pas U compiler/m68k/cpupara.pas U compiler/regvars.pas U compiler/arm/cpupara.pas U compiler/symconst.pas U compiler/mips/cpupara.pas U compiler/paramgr.pas U compiler/psub.pas U compiler/pdecvar.pas U compiler/dbgstabs.pas U compiler/options.pas U packages/fcl-fpcunit/src/testutils.pp git-svn-id: trunk@16180 -
116 lines
2.2 KiB
ObjectPascal
116 lines
2.2 KiB
ObjectPascal
{$mode delphi}
|
|
|
|
uses variants, sysutils;
|
|
|
|
(*$ASSERTIONS ON*)
|
|
|
|
var
|
|
fRefCount: Integer = 0;
|
|
|
|
type
|
|
IA = interface
|
|
['{81E19F6A-90C2-11D9-8448-00055DDDEA00}']
|
|
end;
|
|
TA = class(TObject, IA, IInterface)
|
|
destructor Destroy; override;
|
|
function _AddRef: Integer; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
function _Release: Integer; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
function QueryInterface(constref iid: TGuid; out obj): HResult; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
procedure AfterConstruction; override;
|
|
class function NewInstance: TObject; override;
|
|
end;
|
|
|
|
class function TA.NewInstance: TObject;
|
|
begin
|
|
Result := inherited NewInstance;
|
|
fRefCount := 1;
|
|
end;
|
|
|
|
procedure TA.AfterConstruction;
|
|
begin
|
|
InterlockedDecrement(fRefCount);
|
|
inherited AfterConstruction;
|
|
end;
|
|
|
|
function TA._AddRef: Integer; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
begin
|
|
InterlockedIncrement(fRefCount);
|
|
Result := 0;
|
|
end;
|
|
|
|
function TA._Release: Integer; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
begin
|
|
InterlockedDecrement(fRefCount);
|
|
if fRefCount = 0 then begin
|
|
Writeln('Destroy');
|
|
Self.Destroy;
|
|
end;
|
|
|
|
Result := 0;
|
|
end;
|
|
|
|
function TA.QueryInterface(constref iid: TGuid; out obj): HResult; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
begin
|
|
Result := E_NOINTERFACE;
|
|
end;
|
|
|
|
var
|
|
gone: Boolean = False;
|
|
|
|
destructor TA.Destroy;
|
|
begin
|
|
gone := True;
|
|
Writeln('gone');
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure X;
|
|
var
|
|
v: Variant;
|
|
i: IInterface;
|
|
begin
|
|
Writeln('start of test');
|
|
(* simple test with nil interface *)
|
|
i := nil;
|
|
v := i;
|
|
|
|
i := v;
|
|
|
|
v := 3;
|
|
|
|
(* complex test with refcounting *)
|
|
Writeln('complex test');
|
|
|
|
i := TA.Create;
|
|
assert(fRefCount = 1);
|
|
Writeln('part 1');
|
|
v := i;
|
|
Writeln('part 2');
|
|
//assert(fRefCount = 2);
|
|
|
|
i := nil;
|
|
//assert(fRefCount = 1);
|
|
|
|
Writeln('part 3');
|
|
i := v;
|
|
//assert(fRefCount = 2);
|
|
|
|
Writeln('gone false');
|
|
assert(gone = False);
|
|
i := nil;
|
|
//assert(fRefCount = 1);
|
|
assert(gone = False);
|
|
v := 7; (* TA refcount 0; gone ... note that v := Null doesnt work for some reason *)
|
|
//assert(fRefCount = 0);
|
|
Writeln('goo');
|
|
//assert(gone = True);
|
|
(* "gone" *)
|
|
|
|
Writeln('okay');
|
|
//Halt(0);
|
|
end;
|
|
|
|
begin
|
|
X;
|
|
end.
|