Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi access violation (https://www.delphipraxis.net/186813-access-violation.html)

ford42 2. Okt 2015 09:43

Delphi-Version: XE3

access violation
 
Hey,
ich versuche gerade von einer Unit einer Methode von einer anderen Unit einen Wert zu übergeben, also:

Delphi-Quellcode:
unit Controller;

interface

uses
  Logic;

type
  CalcController = class(TObject)
    private
      m_AddZahl: TBerechnung;
    public
      procedure Notify(p_Action: String; p_Param: String);

  end;

implementation

procedure CalcController.Notify(p_Action: String; p_Param: String);
begin
  if (p_Action = 'Zahl') then
  begin
    m_AddZahl.AddZahl(p_Param);
  end
end;

end.
und

Delphi-Quellcode:
unit Logic;

interface

uses
  System.Classes, System.SysUtils;

type
  TBerechnung = class
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    procedure AddZahl(p_Parameter: String);
  end;

implementation

  procedure TBerechnung.AddZahl(p_Parameter: String);
  var
     eingabeZahl: String;
  begin
    eingabeZahl := eingabeZahl + p_Parameter;
  end;
end.
Aber da kommt bei der Zeile 'm_AddZahl.AddZahl(p_Param);' diese Fehlermeldung 'access violation' :/


Weiß jemand wo ich da den Fehler habe? :)


Vielen Dank im Voraus
Grüße ford42 :)

Aviator 2. Okt 2015 09:46

AW: access violation
 
Du musst das Objekt zuerst instanziieren bevor du es benutzt.

Delphi-Quellcode:
unit Controller;

interface

uses
  Logic;

type
  CalcController = class(TObject)
    private
      m_AddZahl: TBerechnung;
    public
      procedure Notify(p_Action: String; p_Param: String);

  end;

implementation

procedure CalcController.Notify(p_Action: String; p_Param: String);
begin
  if (p_Action = 'Zahl') then
  begin
    m_AddZahl := TBerechnung.Create;  // <----- das hier dabei schreiben
    m_AddZahl.AddZahl(p_Param);
  end
end;

end.
Nur ist es aber auch wichtig, dass du das Objekt m_AddZahl auch wieder mit
Delphi-Quellcode:
m_AddZahl.Free;
freigibst wenn du es nicht mehr benötigst.

ford42 2. Okt 2015 09:53

AW: access violation
 
Danke,
aber jetzt kommt die Fehlermeldung bereits bei 'm_AddZahl := TBerechnung.Create; // <----- das hier dabei schreiben'. :/

Aviator 2. Okt 2015 10:07

AW: access violation
 
Ganz sicher? Bist du mal mit dem Debugger durchgegangen und hast das kontrolliert? Mach das mal zuerst noch. Wenn du nicht weiterkommst, dann häng das komplette Projekt mal hier an.

PS: Welche Delphi Version verwendest du? Das kannst du in deinem Profil hinterlegen.

ford42 2. Okt 2015 10:13

AW: access violation
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ja, ich habe Break-Points gesetzt und als der Fehler kam, war der blaue Pfeil auch bei der Zeile. :/

EDIT: Sry, hab nun alles gepackt

Aviator 2. Okt 2015 10:20

AW: access violation
 
Bitte das komplette Projekt, wenn möglich als ZIP-Datei, anhängen. Hier fehlen sowohl die Projektdatei (*.dpr) also auch die Form-Datei (Gui.dfm).

Edit: OK, die DPR hast du noch nachgeschossen, aber die DFM fehlt trotzdem noch.

nuclearping 2. Okt 2015 10:23

AW: access violation
 
Zitat:

Zitat von ford42 (Beitrag 1317477)
Ja, ich habe Break-Points gesetzt und als der Fehler kam, war der blaue Pfeil auch bei der Zeile. :/

Wie greifst du auf
Delphi-Quellcode:
CalcController
zu? Ich vermute, du instanzierst diesen hier auch nicht?

Und btw:
  1. Klassen deklariert man in Delphi üblicherweise mit einem
    Delphi-Quellcode:
    T
    -Präfix. Also
    Delphi-Quellcode:
    TCalcController = class
    statt
    Delphi-Quellcode:
    CalcController = class
  2. Interne Felder in Klassen deklariert man mit einem
    Delphi-Quellcode:
    F
    -Präfix. Also
    Delphi-Quellcode:
    FAddZahl: TBerechnung;
    statt
    Delphi-Quellcode:
    m_AddZahl: TBerechnung;
  3. Du brauchst nicht von
    Delphi-Quellcode:
    TObject
    ableiten, das sind Klassen standardmäßig. Also
    Delphi-Quellcode:
    TCalcController = class
    ist das gleiche wie
    Delphi-Quellcode:
    TCalcController = class(TObject)

Aviator 2. Okt 2015 10:35

AW: access violation
 
Zitat:

Zitat von nuclearping (Beitrag 1317479)
Zitat:

Zitat von ford42 (Beitrag 1317477)
Ja, ich habe Break-Points gesetzt und als der Fehler kam, war der blaue Pfeil auch bei der Zeile. :/

Wie greifst du auf
Delphi-Quellcode:
CalcController
zu? Ich vermute, du instanzierst diesen hier auch nicht?

Nein tut er nicht. Zumindest sehe ich in der Gui.pas keine Zeile, in der er das Objekt erzeugt.

@ford42: Du kannst auch den Sender auswerten, der bei einem OnClick() Event übergeben wird. So werden aus deinen 14 (oder wie viele es auch immer sind) Prozeduren die du mit dieser Art des Programmierens benötigst eigentlich nur noch 2. Eine die deinen Controller mit 'Zahl' aufruft und eine mit 'Rechenzeichen'.

ford42 2. Okt 2015 12:38

AW: access violation
 
Danke,

hier nun die neue gui:

Delphi-Quellcode:
unit Gui;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Controller;

type
  TFrmCalculator = class(TForm)
    Lb_Gleichung: TLabel;
    Lb_Ergebnis: TLabel;
    Bt_Gleich: TButton;
    Bt_C: TButton;
    Bt_Sechs: TButton;
    Bt_Rueck: TButton;
    Bt_Drei: TButton;
    Bt_Neun: TButton;
    Bt_Null: TButton;
    Bt_Eins: TButton;
    Bt_Durch: TButton;
    Bt_Komma: TButton;
    Bt_Sieben: TButton;
    Bt_Vier: TButton;
    Bt_Mal: TButton;
    Bt_Zwei: TButton;
    Bt_Fuenf: TButton;
    Bt_Acht: TButton;
    Bt_Plus: TButton;
    Bt_Minus: TButton;
    procedure Zahl(Sender: TObject);
    procedure Rechnoperator(Sender: TObject);
    procedure Ereignis(Sender: TObject);
  private
    { Private-Deklarationen }
    m_ControllerAdd: CalcController;
  public
    { Public-Deklarationen }
  end;

var
  FrmCalculator: TFrmCalculator;
implementation

{$R *.dfm}

//Uses

procedure TFrmCalculator.Zahl(Sender: TObject);
var
  zahl: String;
begin
  zahl := TButton(Sender).Caption;
  m_ControllerAdd := CalcController.Create;
  m_ControllerAdd.Notify('Zahl', zahl);
  Lb_Gleichung.Caption := Lb_Gleichung.Caption + zahl;
  m_ControllerAdd.Free;
end;


procedure TFrmCalculator.Ereignis(Sender: TObject);
var
  ereignis: String;
begin
  m_ControllerAdd := CalcController.Create;
  ereignis := TButton(Sender).Caption;
  m_ControllerAdd.Notify('Ereignis', ereignis);
  m_ControllerAdd.Free;
end;


procedure TFrmCalculator.Rechnoperator(Sender: TObject);
var
  rechenoperator: String;
begin
  m_ControllerAdd := CalcController.Create;
  rechenoperator := TButton(Sender).Caption;
  m_ControllerAdd.Notify('Rechenoperator', rechenoperator);
  Lb_Gleichung.Caption := Lb_Gleichung.Caption + rechenoperator;
  m_ControllerAdd.Free;
end;
end.
So meintet ihr es oder? :)

Aviator 2. Okt 2015 13:02

AW: access violation
 
Edit: Naja, den Beitrag bearbeiten während ich meinen schreibe (kannst du zwar nicht wissen) ist nicht so klug, da meine Hinweise jetzt falsch verstanden werden könnten.

Also das was hier jetzt in deiner Haupt Pas-Datei steht sieht schonmal soweit richtig aus. Das was noch fehlt, ist die Instanziierung des m_ControllerAdd Feldes. Um dies noch zu erledigen, solltest du dir einen EventHandler für das FormCreate und das FormDestroy Ereignis erstellen und dann folgendes noch eintragen. Bitte beachte auch noch den Hinweis von nuclearping und benenne deine Klassen noch um und stelle ein T vor den Namen. Typen werden in Delphi laut Konvention immer mit einem T gekennzeichnet. Also sollte aus deiner CalcController Klasse ein TCalcController werden.

Delphi-Quellcode:
procedure TFrmCalculator.FormCreate(Sender: TObject);
begin
  m_ControllerAdd := CalcController.Create;
end;
Delphi-Quellcode:
procedure TFrmCalculator.FormDestroy(Sender: TObject);
begin
  m_ControllerAdd.Free;
end;

In deiner Controller.pas solltest du dir in der CalcController (später TCalcController) Klasse noch einen
Delphi-Quellcode:
constructor
und einen
Delphi-Quellcode:
destructor
im Public Abschnitt anlegen. Im Constructor solltest du folgendes reinschreiben:

Delphi-Quellcode:
constructor CalcController.Create;
begin
  m_AddZahl := TBerechnung.Create;
end;
Im Destructor folgendes:

Delphi-Quellcode:
destructor CalcController.Destroy;
begin
  m_AddZahl.Free;
end;
Aus deiner Notify Procedure kannst du dann die Erzeugung des Objektes wieder entfernen, da dies ja dann im Constructor schon gemacht wird.

Delphi-Quellcode:
procedure CalcController.Notify(p_Action: String; p_Param: String);
begin
  if (p_Action = 'Zahl') then
  begin
    m_AddZahl := TBerechnung.Create; // <---- Das hier wieder entfernen, da im Constructor bereits erledigt
    m_AddZahl.AddZahl(p_Param);
    //m_AddZahl.Free;
  end
  else
  if (p_Action = 'Ergebnis') then
  begin

  end;
end;
Wenn du das alles gemacht hast, dann sollte dein Programm eigentlich funktionieren.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:51 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz