I'm new to delphi/free pascal and I think I have a misconception, since I'm used to java and maybe things can't be approached in the same way. I hope you can help me.
I am using Lazarus v1.6RC1.
I have a class TControl
in a unit uControl
and a class TRed
in a unit TRed
. The unit uControl
has the unit uRed
in uses. The case TControl
has an attribute called FRed
, whose type is TRed
(is an instance of TRed
). The thing is that at a given moment, I need to call a procedure from . My intention is to have access to the instance of from , to be able to access its methods, that's something I did in java, but here it doesn't seem to work. What I am doing is the following:TControl
TRed
TControl
TRed
class TControl
:
TControl = class(TObject)
procedure procesaEntradaRed(pComando : TComando)
public
FRed : TRed;
class TRed
:
TRed = class(TObject)
constructor Create(pControl : TControl)
public
FControl : TControl;
When I install TRed
it TControl
I do it like this:
FRed := TRed.Create(Self);
And the constructor of TRed
is like this:
constructor TRed.Create(pControl : TControl)
begin
FControl := pControl;
end;
The call in which I have the error is this:
FControl.procesaEntradaRed(lComando);
The error message is the following:
uRed.pas(662,12) Error: identifier idents no member "procesaEntradaRed"
I have tried to see which methods were visible TControl
from TRed
, and none of the ones I created in TControl
are visible, although the own methods of TObject
.
I have put only the parts of the code that are involved in the problem to be concise.
Thanks in advance and sorry for the inexperience.
EDIT:
The line where I make the call is found in uRed
, at the end of a procedure whose declaration is:
procedure TRed.UDPRead(AThread: TIdUDPListenerThread; const AData: TidBytes; ABinding: TIdSocketHandle);
However, commenting out that line throws an error when instantiating TRed, passing Self as a parameter:
FRed := TRed.Create(Self);
The error is the following:
uControl.pas(146,69) Error: Incompatible type for arg no. 3: Got > >"UCONTROL.TControl", expected "CONTROLS.TControl"
It says that parameter 3 fails, it is because I also pass 2 strings, I do not show them so as not to confuse.
The fault seems to be in the Self, but I don't know how to fix it.
Your problem is that there are multiple classes with the same name inside the visibility and you don't properly qualify the name of the class you want to reference, and you're actually declaring another one.
We are going to break a long story into several smaller ones.
TControl
TControl is a class already declared in the Controls unit. It is actually quite popular , as it is the source of all controls in FPC, just as it is in Delphi's VCL.
That is, in FPC, just like in the VCL, any control (that is, anything that the user can see on his screen), directly or indirectly inherits from TControl. I follow the recommendation of not declaring other classes with the same names as the classes of the libraries of the tool itself: VCL/RTL/FMX, and less than the classes that are the basis of the class hierarchy.
But Delphi/FPC does support different classes with the same name. For that, let's see.
Identifier rules with the same name.
In Delphi/FPC you can declare data types and variables with the same name, if they are in different visibility levels or in different units.
In case of being in different units, the documentation tells us (free translation made by me):
Going back to your question:
In your case, there are two units that contain the TControl Class, to summarize, let's say they are:
and we also have this other one, which is part of the FPC visual library.
Since you use both units in the unit where you declare the class
TRed
, or else you wouldn't have this problem, the possible solutions are:most recommended : change the name of your class, for example from
TControl
toTMiControl
.change the order in which the units are listed in the clause
uses
, so that the uControl unit appears after the Controls unit.uses
UnaUnidad, OtraUnidad, Controls, uControl;
recommended : Qualify the name of the unit, where you declare the class member, so you don't depend on the order of the uses clause and there is no ambiguity in the declarations
Your code would look like this: