Call a procedure of the invoking class

6

I'm new to delphi / free pascal and I think I have a concept error, because I'm used to java and maybe you can not think about things 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 (it is an instance of TRed ). The fact is that at any given moment, I need to call a procedure of TControl from TRed . My intention is to access the instance of TControl from TRed , to be able to access their methods, that's something I did in java, but here it does not seem to work. What I am doing is the following:

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 in 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 where I have the error is this:

FControl.procesaEntradaRed(lComando);

The error message is as follows:

  

uRed.pas (662.12) Error: identifier idents no member   "processEntradaRed"

I tried to see which methods were visible from TControl from TRed , and none of the ones I created in TControl is visible, although I did the methods proper to TObject .

I have only put the parts of the code that intervene in the problem to be concise.

Thanks in advance and sorry for the inexperience.

EDIT:

The line where I make the call is in uRed , at the end of a procedure whose declaration is:

procedure TRed.UDPRead(AThread: TIdUDPListenerThread; const AData: TidBytes; ABinding: TIdSocketHandle); 

However, when commenting on that line, an error occurs when instantiating TRed, passing Self as a parameter:

FRed := TRed.Create(Self);

The error is as follows:

  

uControl.pas (146,69) Error: Incompatible type for arg no. 3: Got > > "UCONTROL.TControl", expected "CONTROLS.TControl"

Puts that the 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 do not know how to fix it.

    
asked by Daniel Rivers 29.01.2016 в 12:51
source

1 answer

1

Your problem is that there are several classes with the same name within the visibility and you do not correctly qualify the name of the class you want to reference, and you are actually declaring another.

We are going to divide a long story into several small ones.

TControl

TControl is a class already declared in the Controls unit. It is in fact quite popular , since it is the origin of all controls in FPC, as it is in the Delphi VCL.

That is, in FPC, as in the VCL, any control (that is, anything that the user can see on its screen), inherits directly or indirectly from TControl. I follow the recommendation not to declare other classes with the same names as the classes in 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.

Rules of identifiers 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.

If you are in different units, the documentation tells us (free translation by me) :

  

The order in which the units appear in the clause uses determines the order of their initialization and affects the way in which the identifiers are located by the compiler. If two units declare a variable, constant, type, procedure or function with the same name, the compiler will use that of the unit that appears last in the clause uses . (To have access to the identifier in the other unit, you must add the qualifier: NombreUnidad.Identificador .

Going back to your question:

In your case, there are two units that contain the TControl Class, to summarize, let's say they are:

unit uControl;
interface

type
  TControl = class(TObject)
  //etcetera
  end;

and we also have this one, which is part of the visual library of FPC.

unit Controls
interface

type
  TControl = class(TComponent)
  //etcetera

Since you use both units in the unit where you declare the class TRed , or otherwise you would not have this problem, the possible solutions are:

  • more recommended : change the name of your class, for example from TControl to TMiControl .

  • Change the order in which the units are listed in the uses clause, 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 do not depend on the order of the clause uses or there is ambiguity in the statements

Your code would look like this:

TRed = class(TObject)
    constructor Create(pControl : uControl.TControl)
public
    FControl : uControl.TControl;
    
answered by 24.10.2016 / 22:17
source