[fpc-pascal] Delegate Interface class does not seem to be referenced counted
Tony Whyman
tony.whyman at mccallumwhyman.com
Wed Aug 10 14:42:39 CEST 2016
I'm using fpc 3.0.0 and trying to debug a program using COM interfaces.
While reference counting seems to be working fine, there is one
exception, that is when an interface is being used by delegation. In
this case, the object doing the delegation does not seem to be reference
counted. Is this a bug, a feature, or have I missed something?
A simple test program follows. The output is:
Creating TDelegateClass
Creating TMyClass
Creating TDelegateClass
Destroying TDelegateClass
Destroying TDelegateClass
In the example, TMyClass is the interface class doing the delegation and
while TDelegateClass is being destroyed when it goes out of scope,
TMyClass is not.
Tony Whyman
MWA
program project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils, CustApp
{ you can add units after this };
type
{ TDelegateTest }
TDelegateTest = class(TCustomApplication)
protected
procedure DoRun; override;
public
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
procedure WriteHelp; virtual;
end;
IMyInterface = interface
procedure P1;
end;
{ TDelegateClass }
TDelegateClass = class(TInterfacedObject, IMyInterface)
private
procedure P1;
public
constructor Create;
destructor Destroy; override;
end;
{ TMyClass }
TMyClass = class(TInterfacedObject, IMyInterface)
private
FMyInterface: TDelegateClass; // class type
property MyInterface: TDelegateClass
read FMyInterface implements IMyInterface;
public
constructor Create(obj: TDelegateClass);
destructor Destroy; override;
end;
{ TDelegateClass }
procedure TDelegateClass.P1;
begin
writeln('P1');
end;
constructor TDelegateClass.Create;
begin
inherited Create;
writeln('Creating ',ClassName);
end;
destructor TDelegateClass.Destroy;
begin
writeln('Destroying ',ClassName);
inherited Destroy;
end;
{ TMyClass }
constructor TMyClass.Create(obj: TDelegateClass);
begin
inherited Create;
FMyInterface := obj;
writeln('Creating ',ClassName);
end;
destructor TMyClass.Destroy;
begin
writeln('Destroying ',ClassName);
inherited Destroy;
end;
{ TDelegateTest }
procedure TDelegateTest.DoRun;
var Intf: IMyInterface;
Intf2: IMyInterface;
begin
Intf := TMyClass.Create(TDelegateClass.Create);
Intf2 := TDelegateClass.Create;
// stop program loop
Terminate;
end;
constructor TDelegateTest.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
StopOnException := True;
end;
destructor TDelegateTest.Destroy;
begin
inherited Destroy;
end;
procedure TDelegateTest.WriteHelp;
begin
{ add your help code here }
writeln('Usage: ', ExeName, ' -h');
end;
var
Application: TDelegateTest;
begin
Application := TDelegateTest.Create(nil);
Application.Title := 'Interface Delegation Test';
Application.Run;
Application.Free;
end.
More information about the fpc-pascal
mailing list