Cykliczna zależność pomiędzy modułami

0

Robię aplikacje do której się trzeba zalogować i chce zrobić żeby po zalogowaniu po kliknięciu w Button można było się wylogować.
I wszystko by było dobrze gdyby nie:

unit2.pas(44,8) Error: Identifier not found "Form1"
unit2.pas(54) Fatal: There were 1 errors compiling module, stopping

A tutaj kod z tego buttona, w którym po kliknięciu można się wylogować i w nim wywala error.

procedure TForm2.Button1Click(Sender: TObject);
begin
  Form2.Hide;
  Form1.Show;
end;

Jest możliwość że czegoś nie ma w uses, wpisałem tam Unit1 to wywalało error:

unit2.pas(9,24) Fatal: Circular unit reference between Unit2 and Unit1

A tu całe uses:

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons, Menus;

Nie wiem już o co chodzi ; /

3

Ile jeszcze wątków założysz, zanim zaczniesz się uczyć Object Pascala jak należy?

Aby błąd Circular unit reference between Unit2 and Unit1 nie wyskakiwał podczas kompilacji, moduły w obu plikach nie mogą być w tych samych sekcjach, czyli:

tak być nie może (bo błąd):

unit Unit1;

interface

uses
  {...}, Unit2, {...};

implementation

{...}

end.
unit Unit2;

interface

uses
  {...}, Unit1, {...};

implementation

{...}

end.

a tak już może:

unit Unit1;

interface

uses
  {...}, Unit2, {...};

implementation

{...}

end.
unit Unit2;

interface

{...}

implementation

uses
  {...}, Unit1, {...}

{...}

end.

Czyli podsumowując - jeden moduł musi być dodany do listy uses pod interface, a w drugim module musi być dodany do uses w sekcji implementation;

Na przyszłość najpierw poucz się kodzić z jakiegoś kursu, a jak masz problem to nie smaruj od razu nowego wątku, tylko poszukaj tu na forum (jest przecież wyszukiwarka) i przede wszystkim w Google; Miesiąc - dwa temu odpowiadałem dokładnie na ten sam problem, bo pytacz także zamiast najpierw poszukać informacji to założył nowy wątek (ten problem ma wielu początkujących).

0

Jak mam dodać ten 'implementation'

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons, Menus;


type
  { TForm2 }           
1

Poczytać kursy i używać TBrain. To taki komponent, który każdy powinien mieć zainstalowany pomiędzy własnymi uszami. A co do pytania. Nie niszcząc domyślnego kodu dla nowej formatki, nic nie musisz dodawać poza sekcją uses i modułami do których się odnosisz, a w których są formatki jakie chcesz użyć w kodzie innego modułu.

0

Czyli dopełniając słowa @olesio - każdy moduł ma dwie sekcje - Interface i Implementation; Zobacz jak wygląda szablon dla pustego modułu:

unit UnitName;

interface

{ ciało sekcji interface }

implementation

{ ciało sekcji implementation }

end.

Są jeszcze dwie inne dodatkowe sekcje - Initialization i Finalization, ale ich znajomość nie jest Ci na początku potrzebna;


A dopełniając swoje słowa - Circular unit reference wyskoczy tylko i wyłącznie wtedy, gdy moduły w obu plikach są w uses sekcji interface; Natomiast nie będzie tego problemu, jeśli oba moduły w obu plikach będą w uses sekcji implementation;

tutaj błędu także nie będzie:

unit Unit1;

interface

implementation

uses
  Unit2;

end.
unit Unit2;

interface

implementation

uses
  Unit1;

end.

Tak że pamiętaj - oba moduły wskazujące na siebie nie mogą być w obu plikach w uses sekcji interface i to wystarczy że zapamiętasz, a już nigdy ten błąd nie będzie Cię nękał.

0

Dopisałem to:
Unit1

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons, ExtCtrls;
implementation
uses
  Unit2; 

Unit2

unit Unit2;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons, Menus;
implementation
uses
  Unit1;            

Wywala mi error w Unit2 w:

procedure TForm2.Button1Click(Sender: TObject);
begin
  Form2.Hide;
  Form1.Show;
end;  

unit2.pas(46,8) Error: Identifier not found "Form1"

0

Sprawdź w module Unit1 w sekcji interface czy masz tam deklarację zmiennej Form1:

unit Unit1;

interface

{...}

type
  TForm1 = class(TForm)
    {...}
  end;

{...}

var
  Form1: TForm1;

{...}

bo z tego co podałeś wynika że jej tam nie ma; Jeśli nie widzi także zmiennej Form2 to znaczy, że jej deklarację także usunąłeś z modułu.

0

No, tylko że właśnie mam:

var
  Form1: TForm1;
0

Pokaż cały kod obu modułów bo dalej nie chce mi się zgadywać.

0

Unit 1

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons, ExtCtrls;
implementation
uses
  Unit2;

type

  { TForm1 }

  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Login: TLabel;
    Password: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Edit2Change(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

{$R *.lfm}

{ TForm1 }

Unit 2

unit Unit2;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons, Menus;
implementation
uses
  Unit1;


type
  { TForm2 }

  TForm2 = class(TForm)
    BitBtn1: TBitBtn;
    Button1: TButton;
    Label1: TLabel;
    procedure BitBtn1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Label1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form2: TForm2;

{$R *.lfm}

{ TForm2 }                            
0

No i nie dziw się że nie działa, bo zamiast jedynie dodać nowe sekcje w modułach - wszystko pomieszałeś...

  • deklaracja klasy formularza musi być w sekcji interface,
  • deklaracja zmiennej, będącej obiektem klasy formularza także musi być w sekcji interface;

Sekcja ta (interface) jest widoczna dla innych modułów, natomiast implementation nie, dlatego moduły w ogóle nie widzą obiektów Form1 oraz Form2; Prawidłowa konstrukcja:

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons, ExtCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Login: TLabel;
    Password: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Edit2Change(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;

implementation
 
{$R *.lfm}
 
uses   // tutaj miałeś jedynie dodać nową sekcję uses i moduł Unit2
  Unit2;

{...}

end.
unit Unit2;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons, Menus; 

type
  { TForm2 }
 
  TForm2 = class(TForm)
    BitBtn1: TBitBtn;
    Button1: TButton;
    Label1: TLabel;
    procedure BitBtn1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Label1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form2: TForm2;

implementation
 
{$R *.lfm}
 
uses   // tutaj miałeś jedynie dodać nową sekcję uses i moduł Unit1
  Unit1;

{...}

end.

Teraz powinno dać się skompilować; Na przyszłość najpierw się zastanów, a dopiero później wprowadzaj jakiekolwiek modyfikacje na własną rękę, ale przede wszystkim przeczytaj jakikolwiek kurs programowania w Object Pascalu, żeby znów nie trzeba było się głowić.

0

Działa.
Teraz mam error w Logowanie.lpr
Tutaj cały kod:

program Logowanie;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, Unit1, Unit2;

{$R *.res}

begin
  RequireDerivedFormResource := True;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.                      

Tutaj gdzie wywala error:

begin
  RequireDerivedFormResource := True;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.

A tutaj błąd:

Logowanie.lpr(20,1) Error: Can't create object file: Logowanie.exe
Logowanie.lpr(20,1) Fatal: Can't create executable Logowanie.exe

0

Mam uruchomione jako administrator,
poza tym jestem zalogowany na administratorze.

0

Program, który piszesz nie może być otwarty w momencie kompilacji, bo uruchomionego pliku wykonywalnego nie można ani zmodyfikować, ani usunąć; A na to wygląda, że masz go uruchomionego poza środowiskiem, bo nie można się do niego dobrać by po kompilacji utworzyć nowy plik exe.

0

Dzięki, musiałem w procesach usunąć Logowanie.exe ; P

1 użytkowników online, w tym zalogowanych: 0, gości: 1