Re: [fpc-pascal] using Interfaces in descendant classes 2.6.4 vs 3.x

2017-11-03 Thread Graeme Geldenhuys

On 2017-11-03 23:52, Graeme Geldenhuys wrote:

Attached is a sample application reproducing the problem. Compile the
program with FPC 2.6.4 and everything works. Compile it with FPC 3.x and
no interface reference is ever returned.



Yet more testing. Now I've managed to get it to work in all FPC 
versions. Yeah!!!


If I change my class that does interface delegation to the following syntax:

   TClassA = class(TObject, ICmdLine)
   private
FCmdLineParams: TCmdLineImpl;
function GetCmdLineParamsInterface: TCmdLineImpl;
property ChildDelegate: TCmdLineImpl read GetCmdLineParamsInterface 
implements ICmdLine;

   public
 destructor Destroy; override;
   end;


Then it works. Note I changed the function and property definitions.

Still strange that FPC 2.6.4 worked in my prior example and FPC 3.x not. 
I also didn't see any "User Changes" on the wiki about this changed 
behaviour of Interface Delegation.


Regards,
  Graeme

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] using Interfaces in descendant classes 2.6.4 vs 3.x

2017-11-03 Thread Graeme Geldenhuys
Attached is a sample application reproducing the problem. Compile the 
program with FPC 2.6.4 and everything works. Compile it with FPC 3.x and 
no interface reference is ever returned.


Sample output:


===[ compiled with FPC 3.0.0, 3.0.2, 3.0.4 and 3.1.1]
[tmp]$ ./project1
TClassA: ICmdLine interface is not supported!
TClassB: ICmdLine interface is not supported!
TClassC: ICmdLine interface is not supported!


===[ compiled with FPC 2.6.4]
[tmp]$ ./project1
TCmdLineImpl: ICmdLine.MyProc implementation
TCmdLineImpl: ICmdLine.MyProc implementation
TCmdLineImpl: ICmdLine.MyProc implementation



I did some further testing. In the attached project I have a dedicated 
class that implements the interface, then another class that implements 
the interface using interface delegation.  If I change the sample code 
and NOT use interface delegation, but let TClassA directly implement the 
ICmdLine interface, then everything works.


But developers shouldn't need to be forced to do this. FPC support 
interface delegation and the real interface is a lot more complex to 
implement than the very simplified attached example. The nail in the 
coffin is that it used to work in FPC 2.6.4, but is now broken in FPC 3.x



Regards,
  Graeme

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
program project1;

{$mode objfpc}{$H+}
{$interfaces corba}

uses
  Classes, SysUtils;

type
   ICmdLine = interface
   ['{1D27F8F3-C0EE-11E7-87C3-C86000E37EB0}']
 procedure MyProc;
   end;

   // class implementing the interface
   TCmdLineImpl = class(TObject, ICmdLine)
  procedure MyProc;
   end;

   // class implementing the interface via interface delegation
   TClassA = class(TObject, ICmdLine)
   private
FCmdLineParams: TCmdLineImpl;
functionGetCmdLineParamsInterface: ICmdLine;
propertyCmdLineParams: ICmdLine read GetCmdLineParamsInterface implements ICmdLine;
   public
 destructor Destroy; override;
   end;

TClassB = class(TClassA);

TClassC = class(TClassB);



function TClassA.GetCmdLineParamsInterface: ICmdLine;
begin
  if not Assigned(FCmdLineParams) then
FCmdLineParams := TCmdLineImpl.Create;
  Result := FCmdLineParams; // compiler does an implicit: FCmdLineParams as TCmdLineImpl
end;

destructor TClassA.Destroy;
begin
  FreeAndNil(FCmdLineParams);
  inherited Destroy;
end;

{ TCmdLineImpl }

procedure TCmdLineImpl.MyProc;
begin
  writeln(ClassName + ': ICmdLine.MyProc implementation');
end;

var
  c: ICmdLine;
  objA: TClassA;
  objB: TClassB;
  objC: TClassC;
begin
  objA := TClassA.Create;
  try
if Supports(objA, ICmdLine, c) then
  c.MyProc
else
  writeln('TClassA: ICmdLine interface is not supported!');
  finally
FreeAndNil(objA);
  end;

  objB := TClassB.Create;
  try
if Supports(objB, ICmdLine, c) then
  c.MyProc
else
  writeln('TClassB: ICmdLine interface is not supported!');
  finally
FreeAndNil(objB);
  end;

  objC := TClassC.Create;
  try
if Supports(objC, ICmdLine, c) then
  c.MyProc
else
  writeln('TClassC: ICmdLine interface is not supported!');
  finally
FreeAndNil(objC);
  end;
end.

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] using Interfaces in descendant classes 2.6.4 vs 3.x

2017-11-03 Thread Graeme Geldenhuys


On 2017-11-03 23:09, Graeme Geldenhuys wrote:

I looked at the wiki and the FPC 3.x "User Changes" pages and the only
reference to Interface changes is this.
  
http://wiki.freepascal.org/User_Changes_3.0.0#Classes_implementing_forward-declared_interfaces




Please note that I'm not using Interface Forward Declarations in my 
code. The interface definition is fully defined in a separate unit, and 
that unit is referenced in the uses clause (interface section of the 
unit) where TBaseApplication is defined.


So I highly doubt my issue is related to the above URL's topic.


Regards,
  Graeme

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal