Recent

Author Topic: [SOLVED] How to declare external variable?  (Read 626 times)

incendio

  • Jr. Member
  • **
  • Posts: 90
[SOLVED] How to declare external variable?
« on: June 13, 2019, 03:54:13 am »
Hi guys,

I have declared variable in lazarus project file, like this
Code: Pascal  [Select]
  1. var
  2.     ThreadStops: boolean;
  3.     ThreadsRunning: integer;
  4.  

On my Mainform, I have a procedure button click
Code: Pascal  [Select]
  1. procedure TForm1.btnStartClick(Sender: TObject);
  2. var
  3.   ThreadStops : boolean; cvar;external;
  4. begin
  5. end;        
  6.  

But it gave an errors :
Compile Project, Target: multithreadingexample1: Exit code 1, Errors: 2
mainunit.pas(85,26) Error: Cannot declare local variable as EXTERNAL
mainunit.pas(85,30) Fatal: Syntax error, ":" expected but ";" found

How to fix this?
Thanks in advance.



« Last Edit: June 13, 2019, 06:39:02 am by incendio »

440bx

  • Hero Member
  • *****
  • Posts: 1048
Re: How to declare external variable?
« Reply #1 on: June 13, 2019, 04:15:09 am »
Hi guys,

I have declared variable in lazarus project file, like this
Code: Pascal  [Select]
  1. var
  2.     ThreadStops: boolean;
  3.     ThreadsRunning: integer;
  4.  

On my Mainform, I have a procedure button click
Code: Pascal  [Select]
  1. procedure TForm1.btnStartClick(Sender: TObject);
  2. var
  3.   ThreadStops : boolean; cvar;external;
  4. begin
  5. end;        
  6.  

But it gave an errors :
Compile Project, Target: multithreadingexample1: Exit code 1, Errors: 2
mainunit.pas(85,26) Error: Cannot declare local variable as EXTERNAL
mainunit.pas(85,30) Fatal: Syntax error, ":" expected but ";" found

How to fix this?
Thanks in advance.
If I understood you correctly, you just want to use the ThreadStops variable in more than one unit.  If that is the case, simply declare the ThreadStops variable in another unit (call it Globals.pas - if you want) which is then used by the other units where you want it to be accessible. 

You don't need (nor will it work) to declare it as a cvar and/or external.  Those are used for something completely different.

HTH.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: How to declare external variable?
« Reply #2 on: June 13, 2019, 04:17:18 am »
As explained by 440bx, add the unit where you declared the variable to the uses section in mainunit:
Code: Pascal  [Select]
  1. unit mainunit;
  2. ...
  3. implementation
  4.  
  5. uses
  6.  ...., Globals;
  7. ...


incendio

  • Jr. Member
  • **
  • Posts: 90
Re: How to declare external variable?
« Reply #3 on: June 13, 2019, 04:33:33 am »
Thanks guys,

That's worked.

I came from C++ environment. Usually in C++, I declared global variables in its project file.

When a form or unit (in this case) need to access this variable, in C++, i use this code in that unit
Code: Pascal  [Select]
  1. extern int MyGlobalVar;

In this case, I don't need a unit to holds my global variable.

So, in Lazarus, is there a same handling like C++ ? If not, I will use your suggestion. Thanks anyway.

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: How to declare external variable?
« Reply #4 on: June 13, 2019, 04:53:40 am »
Here I go.  :(

If you really want to use C++ style:
1-Declare your variable using cvar:
Code: Pascal  [Select]
  1. var
  2.   test : integer; cvar;

2-Where you want to use it, add external to the same declaration:
Code: Pascal  [Select]
  1. var
  2.   test: integer; cvar; external;

Now unlike usual Pascal variables, this is case sensitive.

incendio

  • Jr. Member
  • **
  • Posts: 90
Re: How to declare external variable?
« Reply #5 on: June 13, 2019, 04:58:56 am »
Here I go.  :(

If you really want to use C++ style:
1-Declare your variable using cvar:
Code: Pascal  [Select]
  1. var
  2.   test : integer; cvar;

2-Where you want to use it, add external to the same declaration:
Code: Pascal  [Select]
  1. var
  2.   test: integer; cvar; external;

Now unlike usual Pascal variables, this is case sensitive.

I have tried this in first post, it gave an error.

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: How to declare external variable?
« Reply #6 on: June 13, 2019, 05:05:32 am »
You probably did not declare it in the public section of the unit, before implementation.

This should work:
Code: Pascal  [Select]
  1. var
  2.   test : integer; cvar;
  3.  
  4. implementation

This will not work:
Code: Pascal  [Select]
  1. implementation
  2.  
  3. var
  4.   test : integer; cvar;

incendio

  • Jr. Member
  • **
  • Posts: 90
Re: How to declare external variable?
« Reply #7 on: June 13, 2019, 05:13:44 am »
Hmmn, there is no implementation keyword in project file.

Here are the codes in project file
Code: Pascal  [Select]
  1. program MultiThreadingExample1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   // for multi threading the cthreads unit must be used on unix systems:
  7.   // for example: Linux, MacOSX, FreeBSD, Solaris
  8.   {$IFDEF UNIX}
  9.   cthreads,
  10.   {$ENDIF}
  11.   Interfaces, // this includes the LCL widgetset
  12.   Forms, MainUnit, dm;
  13.  
  14. var
  15.   ThreadStops: boolean; cvar;
  16.   ThreadsRunning: integer; cvar;
  17.  
  18. begin
  19.   Application.Initialize;
  20.   Application.CreateForm(TForm1, Form1);
  21.   Application.CreateForm(TDtM, DtM);
  22.   Application.Run;
  23. end.
  24.  

Those codes from Lazarus example, MultiThreadingExample1, only add variable declaration section.

And this is the codes from main unit
Code: Pascal  [Select]
  1. procedure TForm1.btnStartClick(Sender: TObject);
  2. var
  3.   ThreadStops : boolean; cvar; external;
  4. begin
  5. end;
  6.  

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: How to declare external variable?
« Reply #8 on: June 13, 2019, 05:22:11 am »
I was just guessing.  :(

In your case the compiler did not emit any reference to the variable because it was not "used". Not used in Pascal, so not needed.

Edit:
Also, I don't think it works to declare it as a local variable to a procedure, function, or method.
« Last Edit: June 13, 2019, 05:24:52 am by engkin »

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: How to declare external variable?
« Reply #9 on: June 13, 2019, 05:32:40 am »
Declare it with export:
Code: Pascal  [Select]
  1.   test: integer; cvar; export;

incendio

  • Jr. Member
  • **
  • Posts: 90
Re: How to declare external variable?
« Reply #10 on: June 13, 2019, 05:35:51 am »
Declare it with export:
Code: Pascal  [Select]
  1.   test: integer; cvar; export;

Same error message.

440bx

  • Hero Member
  • *****
  • Posts: 1048
Re: How to declare external variable?
« Reply #11 on: June 13, 2019, 05:40:38 am »
In this case, I don't need a unit to holds my global variable.
Just something for you to think about, having all the globals in one unit makes the maintenance of the code easier.  It's much cleaner to have all the globals in one place/unit/(.h in the case of C/C++) than scattered all over.



using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

incendio

  • Jr. Member
  • **
  • Posts: 90
Re: How to declare external variable?
« Reply #12 on: June 13, 2019, 05:49:40 am »
In this case, I don't need a unit to holds my global variable.
Just something for you to think about, having all the globals in one unit makes the maintenance of the code easier.  It's much cleaner to have all the globals in one place/unit/(.h in the case of C/C++) than scattered all over.

That's what I am doing, I placed all global variables in project file, in C++, it is the bpr file.

I am trying to do the same with Lazarus, put all global variables in its project file, the lpr file.

440bx

  • Hero Member
  • *****
  • Posts: 1048
Re: How to declare external variable?
« Reply #13 on: June 13, 2019, 05:59:53 am »
That's what I am doing, I placed all global variables in project file, in C++, it is the bpr file.

I am trying to do the same with Lazarus, put all global variables in its project file, the lpr file.
In Pascal (Delphi/FPC) the (sort of) equivalent is to have a separate unit for all the globals.  The reason has to do with the fact that scoping is different in Pascal/FPC than in C/C++.

Don't think of your lpr (lazarus project file) as being "global", it isn't.   Just like any other unit, it can only access what it "uses" and within what it "uses", only those things that are declared in the "interface" portion of a unit.  Anything in the implementation section is private to the unit.

You will need to adapt your thinking about scopes to how they are implemented in Pascal (actually, much cleaner, simpler and sensible.) That means, you do have a little bit of a learning curve but, it really isn't bad.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

incendio

  • Jr. Member
  • **
  • Posts: 90
Re: How to declare external variable?
« Reply #14 on: June 13, 2019, 06:38:44 am »
I think, found the way to solved the problem without need separated unit to hold global variables.

I don't know if this is the right method to do, but it worked just fine.

Here are the declaration in lpr file
Code: Pascal  [Select]
  1. var
  2.   ThreadStops: boolean; cvar; export;
  3.   ThreadsRunning: integer;cvar; export;
  4.  

and here are the declaration in the unit that will use variable in that lpr file
Code: Pascal  [Select]
  1. unit MainUnit;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.  
  9. type
  10.  
  11.   { TForm1 }
  12.  
  13.   TForm1 = class(TForm)
  14.     btnStart: TButton;
  15.     procedure btnStartClick(Sender: TObject);
  16.     procedure FormCreate(Sender: TObject);
  17.   private
  18.   public
  19.   end;
  20.  
  21. var
  22.   Form1: TForm1;
  23.   ThreadStops : boolean; cvar;external;
  24.   ThreadsRunning : integer; cvar;external;
  25.  
  26. implementation
  27.  

Here is the code to test it
Code: Pascal  [Select]
  1. procedure TForm1.btnStartClick(Sender: TObject);
  2. begin
  3.   ShowMessage(IntToStr(ThreadsRunning));
  4. end;
  5.  

Thanks all for your help.