Forum > General

"Identifier idents no member" when using "implements" keyword

(1/2) > >>

PawelO:
Hello,


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$interfaces corba} IMyInterface = interface  ['IMyInterface']  procedure DoStuff;end; TClassA = class(IMyInterface)  procedure DoStuff;end; TClassB = class(IMyInterface)private  FClassA: TClassA;public  constructor Create;  destructor Destroy; override;  property ClassA: TClassA read FClassA implements IMyInterface;end;
TClassA implements an interface. TClassB implements same interface using TClassA with "implements" keyword. Lazarus code completion shows DoStuff as available TClassB method. However this:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var  classB: TClassB; classB.DoStuff;
Causes compilation error:

Error: identifier idents no member "DoStuff"

It works only after casting to interface type:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var  classB: TClassB;  myInterface: IMyInterface; myInterface := classB;myInterface.DoStuff;
Is this a bug or it should work that way by design?

Thaddy:
It is not a bug. The classes need to be derived from TInterfacedObject.
You also can't use CORBA interfaces, because of that: it needs queryinterface, addref and release implemented.
Complete example:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$ifdef fpc}{$mode delphi}{$interfaces com}{$endif}uses classes;type IMyInterface = interface['{2D9E9882-BB2F-4AB7-880D-4B82C2C4C425}']  procedure DoStuff;end; TClassA = class(TInterfacedObject,IMyInterface)  procedure DoStuff;end; TClassB = class(TInterfacedObject,IMyInterface)private  FClassA: IMyInterface;public  constructor Create(const AValue:IMyInterface);virtual;  property ClassA: IMyInterface read FClassA implements IMyInterface;end; procedure TClassA.DoStuff;begin  writeln('Whatever I have to do');end; constructor TClassB.Create(const aValue:IMyInterface);begin  inherited create;  FClassA := aValue;end; var  test:IMyInterface;begin  test := TClassB.Create(TClassA.Create);// both created as IMyInterface, not as class  test.DoStuff; // delegates to ClassA through QueryInterface, hence COM not CORBAend.Above also compiles in Delphi. Don't use CORBA with delegates.

Martin_fr:
His issue is that he can't call

   The_Class_declared_var.MethodOfInterface;  // <= this will not cast to interface

The class could have any number of interfaces, so it wouldn't even be clear wich intf to cast to.

You have to either put the The_Class_declared_var in a typecast to the interface type you want, or assign it to a variable declared as the interface type and use that var.



Afaik, it is intended behaviour (and no bug) that

   The_Class_declared_var.MethodOfInterface;

does not work (so long as the class does not have its own method of name "MethodOfInterface" in scope.

And afaik that behaviour is the same for both types of interface.

Martin_fr:
Maybe use "type helper" instead...

Thaddy:
@Martin_fr

I know!! what the issue is, therefor I wrote a proper example based on his own code.
Although it also exposes a bug in FPC compared to Delphi: FPC leaks, Delphi NOT.
- this is a very, very old bug and known for "implements"-
And NO, it doesn't work alike for both interface types: QueryInterface is a COM concept and called internally.
You can solve that for CORBA by implementing QueryInterface manually.
CORBA interfaces are raw interfaces and do not rely on some infrastructure. COM interfaces expect IInterface fully implemented (QueryInterface, Addref and release)

I will fix the leak. There is a way and keeps compatibility with Delphi too.
A correct CORBA example would take many more lines of code. Silly concept.

Navigation

[0] Message Index

[#] Next page

Go to full version