Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Zugriffsverletzung bei Adresse 0043815C in Modul 'xxx.exe'. Lesen von Adresse (https://www.delphipraxis.net/204820-zugriffsverletzung-bei-adresse-0043815c-modul-xxx-exe-lesen-von-adresse.html)

Moien 2. Jul 2020 13:56

Delphi-Version: 10.2 Tokyo

Zugriffsverletzung bei Adresse 0043815C in Modul 'xxx.exe'. Lesen von Adresse
 
Hallo Zusammen,

Ich habe ein Delphi-Programm und versuche, über mein Programm Variablen auf den OPC UA-Server zu schreiben. Ich erhalte den folgenden Fehler:
"TOPCClient.WriteItem - Exception: Zugriffsverletzung bei Adresse 0043815C in Modul 'xxx.exe'. Lesen von Adresse 00000000".

Ich habe einen Teil meines Codes hier kopiert, in dem der Fehler auftritt.

Delphi-Quellcode:
// -----------------------------------------------------------------------------
// WriteItem - Write OPCUA Item
// -----------------------------------------------------------------------------
function TOPCClient.WriteItem(Name: String; ItemValue: Variant): Boolean;
Var
  I : Integer;
  ItemFound : Boolean;
  label
  GoToWriteToOPCServer;
begin
  ItemFound := False;
  Result   := FALSE;
  try
    for I := 0 to Length(OPCServerItemArray)-1 do begin
      if (AnsiMatchStr(Name, OPCServerItemArray[I].ItemName)) then begin
        ItemFound := True;
        WriteToOPCServerArray[WriteIndex].ItemName := Name;
        WriteToOPCServerArray[WriteIndex].Value := ItemValue;
        WriteToOPCServerArray[WriteIndex].Source := OPCServerItemArray[I].Source;
        WriteIndex := WriteIndex+1;
        Result := True;
        GoTo GoToWriteToOPCServer;
      end;
    end;

    if not(ItemFound) then begin
      Meldung(0,'TOPCClient.WriteItem: ' + Name + ' (is not found)');
    end;
    GoToWriteToOPCServer:
    if (WriteIndex = NoVarToWrite)then begin
      WriteMultipleIdx := WriteIndex;
      WriteIndex:= 0;
      WriteMultipleItems;
    end else if (WriteIndex > NoVarToWrite) then begin
      Meldung(0,'TOPCClient.WriteItem - Exception: The write array is too long!'+ 'WriteIndex = '+ IntToStr(WriteIndex));
    end;

  except
    on E: Exception do begin
      Meldung(0,'TOPCClient.WriteItem - Exception: ' + E.Message + ' info: ' + Name + ' WriteIndex: ' + IntToStr(WriteIndex) + ' I = ' + IntToStr(I));
    end;
  end;
end;

// -----------------------------------------------------------------------------
// WriteMultipleItem - Write OPCUA Item
// -----------------------------------------------------------------------------

Procedure TOPCClient.WriteMultipleItems;
Var
  I : Integer;
  Results : OleVariant;
  ExpandedText : WideString;
begin
  SetLength(WriteValueArguments,WriteMultipleIdx);
  try
    if (connected) then begin
      for I := 0 to WriteMultipleIdx-1 do begin
        WriteValueArguments[I] := CoUAWriteValueArguments.Create;
        WriteValueArguments[I].EndpointDescriptor.UrlString := Url_String;
        ExpandedText := 'nsu='+ nsu + ';s=' + S0 + '.' + WriteToOPCServerArray[I].Source + '.' + WriteToOPCServerArray[I].ItemName;
        WriteValueArguments[I].NodeDescriptor.NodeId.ExpandedText := ExpandedText;
        WriteValueArguments[I].Value := WriteToOPCServerArray[I].Value;
      end;

      WriteArguments := VarArrayCreate([0, WriteMultipleIdx-1], varVariant);
      for I := 0 to WriteMultipleIdx-1 do begin
        WriteArguments[I] := WriteValueArguments[I];
      end;

      TVarData(Results).VType := varArray or varVariant;
      TVarData(Results).VArray := PVarArray(OPCUAClientMultiWrite.WriteMultipleValues(
      PSafeArray(TVarData(WriteArguments).VArray)));
    end else begin
      Meldung(0,'TOPCClient.WriteAllItems: not connected to the OPC UA Server');
    end;
  except
    on E: Exception do begin
      Meldung(0,'TOPCClient.WriteMultipleItems - Exception: ' + E.Message);
    end;
  end;
end;
Ich würde mich über Ihre Unterstützung freuen.

LG
Moien

Rollo62 2. Jul 2020 15:48

AW: Zugriffsverletzung bei Adresse 0043815C in Modul 'xxx.exe'. Lesen von Adresse
 
Wieso arbeitest Du mir Goto ?

Delphi-Quellcode:
var
  ItemFound : Boolean;
  label
  GoToWriteToOPCServer;
begin
  try
    for I := 0 to Length(OPCServerItemArray)-1 do begin
        GoTo GoToWriteToOPCServer;
    end;

...

    GoToWriteToOPCServer:
...
Das sollte man nicht mehr Nutzen, nur wenn man genau weiss was da passiert (und selbst dann nicht).

Aus for-Schleifen springt man mit break raus

Delphi-Quellcode:
    for I := 0 to Length(OPCServerItemArray)-1 do begin
      if Bedingung then
        break;
    end;

himitsu 2. Jul 2020 16:48

AW: Zugriffsverletzung bei Adresse 0043815C in Modul 'xxx.exe'. Lesen von Adresse
 
Jupp, also erstmal das Goto ist hier sowieso nutzlos,
denn mit [OH]Break;[/OH] die Schleife abbrechen reicht vollkommen,
denn das IF vor dem Meldung überspringt diesen Teil sowieso.

Außerdem Doppelte Infos:
Wieso ItemFound, wenn Result die selbe Information enthält?

Zitat:

Lesen von Adresse 00000000
Die Null sagt dir, dass da auf ein NIL zugegriffen wird.
00000000 oder 00000123 ist alles NIL, letzteres mit einem Offset, z.B. wenn man auf eine Variable zugreift, die ja bissl unterhalb der gezeigten Adresse liegt.

NIL lässt sich ja leicht prüfen.

Bei großen Zeigern-Adressen ist ein "ungültiger" Zeiger schuld,
wie z.B. eine nicht-initialisierte Variable oder ein Zeiger auf ein Objekt, welches bereits freigegeben wurde.

Zitat:

Zugriffsverletzung bei Adresse 0043815C in Modul 'xxx.exe'
Nennt dir die Stelle ... die könnte man z.B. im Debugger (CPU-Ansicht) oder in der MAP-Datei bzw. Debuginfos suchen.

Die Adresse hilft aber selten, da es die Stelle ist wo es knallte, aber meistens eine aufrufende Stelle den Fehler verursachte,
drum schaut man in den Stacktrace, von wo es her kam. (Debugger, Eurekalog oder Dergleichen)



Egal was du machst, ich empfehle die Benutzung des Debuggers, um die Zeile zu bekommen wo es knallte.
Wir können hier nicht helfen, da uns niemand gesagt hat WO es knallt (Zeile)
und wir auch garnicht wiessen was Vaiablen außerhalb des gezeigten Codes drin seht.

Der Code selber hat jetzt erstmal scheinbar keine "gravirenden" Fehler, die mit jetzt direkt ins Auge gefallen sind.
Abgesehn von unnötigen Variablen, unnötigen Sprüngen und bissl sinnfreien Kommentaren (was die machen erklärt bereits der Name)
Obwohl: Warum fehlt "OPCUA" in den Methodennamen? Und dann sind die Kommentare plötzlich komplett nutzlos. :zwinker:

hoika 2. Jul 2020 17:14

AW: Zugriffsverletzung bei Adresse 0043815C in Modul 'xxx.exe'. Lesen von Adresse
 
Hallo,
ich würde MadExcept zu Hilfe nehmen.

Dalai 3. Jul 2020 02:15

AW: Zugriffsverletzung bei Adresse 0043815C in Modul 'xxx.exe'. Lesen von Adresse
 
Da die anderen bereits die groben Fehler genannt haben, kann ich die überspringen. (Goto *schauder* *schüttel* hab ich zuletzt vor laaanger Zeit als Programmieranfänger in Turbo Pascal benutzt.) Andererseits habe ich den Eindruck, dass hier noch globale Variablen im Spiel sind (ja, es könnten auch Klassenvariablen sein).

Zitat:

Zitat von Moien (Beitrag 1468735)
Ich habe einen Teil meines Codes hier kopiert, in dem der Fehler auftritt.

In welcher Zeile kommt es zur Exception? Hast du mal den Debugger (F8 bzw. F7) bemüht und/oder Breakpoints im Code gesetzt?

Delphi-Quellcode:
Procedure TOPCClient.WriteMultipleItems;
[...]
begin
[...]
      for I := 0 to WriteMultipleIdx-1 do begin
        WriteValueArguments[I] := CoUAWriteValueArguments.Create;
Sicher, dass das so richtig ist? Normalerweise wird ein Konstruktor mit dem Namen des Typs der Klasse gerufen, also TKlasse.Create, nicht Klasse.Create. Heißt der Typ deiner Klasse so oder ist das eine Variable?

Grüße
Dalai

Jasocul 3. Jul 2020 06:37

AW: Zugriffsverletzung bei Adresse 0043815C in Modul 'xxx.exe'. Lesen von Adresse
 
Wenn wir schon auf grundlegende Probleme in dem Source eingegangen wird, möchte ich noch eine Anmerkung loswerden.

Zitat:

Zitat von Moien (Beitrag 1468735)
Delphi-Quellcode:
function TOPCClient.WriteItem(Name: String; ItemValue: Variant): Boolean;
Var
  I : Integer;
begin
  try
    for I := 0 to Length(OPCServerItemArray)-1 do begin
...
    end;
...
  except
    on E: Exception do begin
      Meldung(0,'TOPCClient.WriteItem - Exception: ' + E.Message + ' info: ' + Name + ' WriteIndex: ' + IntToStr(WriteIndex) + ' I = ' + IntToStr(I));
    end;
  end;
end;

Das "I" in deiner Exception ist mit Vorsicht zu genießen, da Schleifenvariablen nach dem Durchlauf undefiniert sein können. Ob das bei einer Exception in der Schleife auch so ist, entzieht sich allerdings meiner Kenntnis. Verlassen würde ich mich jedenfalls nicht darauf.

Rolf Frei 3. Jul 2020 15:29

AW: Zugriffsverletzung bei Adresse 0043815C in Modul 'xxx.exe'. Lesen von Adresse
 
Da fehlt leider so eingies an wichtigen Details um etwas genaueres zu sagen. Was aber dein Fehler aussagt ist, dass du da einen NIL Pointer adressierst. Also zum Beispiel ein nicht initialisiertes Object oder ein Array. ("Lesen von Adresse 00000000" beduetet zugriff auf NIL)

Moien 6. Jul 2020 07:37

AW: Zugriffsverletzung bei Adresse 0043815C in Modul 'xxx.exe'. Lesen von Adresse
 
Vielen Dank für die Feedbacks.
Ich habe "Break" anstelle von "GoTo" verwendet, aber ich erhalte immer noch die Exception.
Die Exception kommt in dieser Zeile zum ersten Mal:

Delphi-Quellcode:
WriteArguments := VarArrayCreate([0, WriteMultipleIdx-1], varVariant);


LG
Moien

Moien 6. Jul 2020 07:40

AW: Zugriffsverletzung bei Adresse 0043815C in Modul 'xxx.exe'. Lesen von Adresse
 
Was brauchst du als weiteren Input?
LG
Moien
Zitat:

Zitat von Rolf Frei (Beitrag 1468820)
Da fehlt leider so eingies an wichtigen Details um etwas genaueres zu sagen. Was aber dein Fehler aussagt ist, dass du da einen NIL Pointer adressierst. Also zum Beispiel ein nicht initialisiertes Object oder ein Array. ("Lesen von Adresse 00000000" beduetet zugriff auf NIL)


Rolf Frei 6. Jul 2020 12:53

AW: Zugriffsverletzung bei Adresse 0043815C in Modul 'xxx.exe'. Lesen von Adresse
 
Was ist OPCServerItemArray / WriteToOPCServerArray und wo/wie erstellst du das? Was hat WriteMultipleIdx für einen Wert und wo/wie wird dieser gesetzt?

Versuche doch ein kleines Beispielprojekt zu machen, das den Fehler reproduziert. Anhand deines Codes ist der Fehler nicht einfach zu finden und vermutlich liegt die Quelle des Fehlers garnicht in diesem Code sondern ausserhalb, wo du Objekte, etc. erstellst/abfüllst, die du hier nutzt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:00 Uhr.

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