fpc/tests/test/tinterface4.pp
joost 07bf44517c * Merged XPCom branch into trunk, added support for constref and changed
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 -
2010-10-17 20:58:22 +00:00

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.