Forum > General
"Identifier idents no member" when using "implements" keyword
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