AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Zugriffsverletzung

Ein Thema von schand99 · begonnen am 25. Jul 2016 · letzter Beitrag vom 27. Jul 2016
Antwort Antwort
schand99

Registriert seit: 7. Nov 2013
Ort: Südtirol
43 Beiträge
 
Delphi XE8 Enterprise
 
#1

AW: Zugriffsverletzung

  Alt 26. Jul 2016, 11:00
Der if / else if block greift immer, das wird wie schon weiter oben beschrieben vor dem Aufrufen der Funktion sichergestellt. 'res' ist der Rückgabewert aus der dll.
Nun werden die dll-Aufrufe mit den übergebenen Werten und den Rückgaben in eine Log-Datei geschrieben. Alle läuft fehlerfrei bis zum 62. Aufruf einer x-beliebigen DLL-Funktion, nach 62. Aufruf wird beim Verlassen der Funktion Udllcall der Fehler wegen Schutzverletzung ausgelöst
  Mit Zitat antworten Zitat
Benedikt Magnus

Registriert seit: 6. Jul 2012
Ort: Bonn
190 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Zugriffsverletzung

  Alt 26. Jul 2016, 11:25
Mal anders gedacht: Wenn sich aufgrund fehlender Dokumentation der Grund für die Zugriffsverletzung nicht finden lässt, wie wäre dann ein Workaround, die DLL nach jedem 62. Aufruf neuzuladen?
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#3

AW: Zugriffsverletzung

  Alt 26. Jul 2016, 12:32
Alle läuft fehlerfrei bis zum 62. Aufruf einer x-beliebigen DLL-Funktion, nach 62. Aufruf wird beim Verlassen der Funktion Udllcall der Fehler wegen Schutzverletzung ausgelöst
Das klingt so als ob da ein Pointer incrementiert würde. Nur gibt der vorhandene Sourcecode da nichts her. Die Prüfung auf Bereichsüberprüfung ist aber eingeschaltet?

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
schand99

Registriert seit: 7. Nov 2013
Ort: Südtirol
43 Beiträge
 
Delphi XE8 Enterprise
 
#4

AW: Zugriffsverletzung

  Alt 26. Jul 2016, 13:04
Ich glaub ich werd welk...

Der Tipp von Benedikt Magnus, das ist DER Tipp. Dachte ich mir. Habe das Programm so umgebaut, dass die DLL für jeden Aufruf dynamisch geladen wird. Die ganze Funktion sieht nun so aus:
Delphi-Quellcode:
Function UDllCall(FType, FName: String; TKM, XVar: Double): Double;
 Type
  TFreon1Para = function(ref: PAnsiChar; var dlret: Double): Boolean; stdcall;
  TFreon2Para = function(ref: PAnsiChar; t: Double; var dlret: Double): Boolean; stdcall;
  TFreon3Para = function(ref: PAnsiChar; t, p: Double; var dlret: Double): Boolean; stdcall;
 Var
  hDLL: THandle;
  FarProc1: TFreon1Para;
  FarProc2: TFreon2Para;
  FarProc3: TFreon3Para;
  Temp, res: Double;
  Refr: PAnsiChar;
  Erg: WordBool;
  f: TextFile;
  Adw: String;
Begin
   //GetMem(Refr, 16);
   Temp := 273.15 + TKM;
   // Berechnen der Stoffwerte
   Refr := PAnsiChar('r407c');
   if FType = 'R404Athen
      Refr := PAnsiChar('r404a')
   else if FType ='R407Cthen
      Refr := PAnsiChar('r407c')
   else if FType ='R134Athen
      Refr := PAnsiChar('r134a')
   else if FType ='R410Athen
      Refr := PAnsiChar('r410a')
   else if FType ='R507then
      Refr := PAnsiChar('r507')
   else if FType ='R22then
      Refr := PAnsiChar('r22');
   hDLL := LoadLibrary(DLLName);
   if hDLL = 0 then
      begin

      end
     else
      Begin
         if Uppercase(FName) = 'S_TCthen
            Begin
               FarProc1 := GetProcAddress(hDLL, 'S_tc');
               if Assigned(FarProc1) then
                  erg := FarProc1(refr, res)
                 else
                  res := -999999;
               //erg := S_tc(Refr, res);
            End;
         if Uppercase(FName) = 'S_PCthen
            Begin
               FarProc1 := GetProcAddress(hDLL, 'S_pc');
               if Assigned(FarProc1) then
                  erg := FarProc1(refr, res)
                 else
                  res := -999999;
               //erg := S_pc(Refr, res);
            End;
         if Uppercase(FName) = 'S_P_Dthen
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_p_d');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_p_d(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_H_Lthen
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_h_l');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_h_l(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_H_Vthen
            Begin
               FarProc3 := GetProcAddress(hDLL, 'S_h_v');
               if Assigned(FarProc3) then
                  erg := FarProc3(refr, Temp, XVar, res)
                 else
                  res := -999999;
               //erg := S_h_v(Refr, Temp, XVar, res);
            End;
         if Uppercase(FName) = 'S_SIGMA_Lthen
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_sigma_l');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_sigma_l(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_VISC_Lthen
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_visc_l');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_visc_l(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_VISC_V'then
            Begin
               FarProc3 := GetProcAddress(hDLL, 'S_visc_v');
               if Assigned(FarProc3) then
                  erg := FarProc3(refr, Temp, XVar, res)
                 else
                  res := -999999;
               //erg := S_visc_v(Refr, Temp, XVar, res);
            End;
         if Uppercase(FName) = 'S_V_Lthen
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_v_l');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_v_l(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_V_Vthen
            Begin
               FarProc3 := GetProcAddress(hDLL, 'S_v_v');
               if Assigned(FarProc3) then
                  erg := FarProc3(refr, Temp, XVar, res)
                 else
                  res := -999999;
               //erg := S_v_v(Refr, Temp, XVar, res);
            End;
         if Uppercase(FName) = 'S_CP_Lthen
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_cp_l');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_cp_l(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_LAMBDA_Lthen
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_lambda_l');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_lambda_l(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_LAMBDA_Vthen
            Begin
               FarProc3 := GetProcAddress(hDLL, 'S_lambda_v');
               if Assigned(FarProc3) then
                  erg := FarProc3(refr, Temp, XVar, res)
                 else
                  res := -999999;
               //erg := S_lambda_v(Refr, Temp, XVar, res);
            End;
         if Uppercase(FName) = 'S_VSthen
            Begin
               FarProc3 := GetProcAddress(hDLL, 'S_vs');
               if Assigned(FarProc3) then
                  erg := FarProc3(refr, Temp, XVar, res)
                 else
                  res := -999999;
               //erg := S_vs(Refr, Temp, XVar, res);
            End;
         if Uppercase(FName) = 'S_T_Dthen
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_t_d');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, XVar, res)
                 else
                  res := -999999;
               //erg := S_t_d(Refr, XVar, res);
            End;
         if Uppercase(Fname) = 'S_CVthen
            Begin
               FarProc3 := GetProcAddress(hDLL, 'S_cv');
               if Assigned(FarProc3) then
                  erg := FarProc3(refr, Temp, XVar, res)
                 else
                  res := -999999;
               //erg := S_cv(Refr, Temp, XVar, res);
            End;
      End;
   if Erg then
      Adw := 'erg True'
     else
      Adw := 'erg False';

   AssignFile(f, Logfile);
   if FileExists(Logfile) then
      Append(f)
     else
      Rewrite(f);
   WriteLn(f, FType + ' -> ' + FName + ' -> ' + FloatToStr(TKM) + ' -> ' + FloatToStr(XVar) + ' => ' + FloatToStr(res)+ ' / ' + Adw);
   CloseFile(f);
   erg := FreeLibrary(hDLL);
   Result := res;
End;
Aber leider: nach dem 62zigsten Aufruf der Funktion ist Ende. Genau der selbe Fehler wegen Schutzverletzung. Querprüfung mit dem alten VB6-Code zeigt, dass die an die DLL übergebenen Werte weitestgehend übereinstimmen. Im VB6 gibt es aber keinerlei Probleme.

Bereichsprüfung sehe ich soeben in einem anderen Post. Ist das eine Compileroption?

Geändert von schand99 (26. Jul 2016 um 13:08 Uhr)
  Mit Zitat antworten Zitat
bra

Registriert seit: 20. Jan 2015
711 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#5

AW: Zugriffsverletzung

  Alt 26. Jul 2016, 13:26
Wenn bei FName was ungültiges übergeben wird, hast du wieder einen Haufen uninitialisierte Variablen
  Mit Zitat antworten Zitat
schand99

Registriert seit: 7. Nov 2013
Ort: Südtirol
43 Beiträge
 
Delphi XE8 Enterprise
 
#6

AW: Zugriffsverletzung

  Alt 26. Jul 2016, 13:39
Wenn bei FName was ungültiges übergeben wird, hast du wieder einen Haufen uninitialisierte Variablen
Stimmt theoretisch, passiert aber definitiv nicht. Da der dynamische Aufruf der dll ohnehin keine Besserung gebracht hat, werde ich wieder auf Statisch umbauen. Für die Ausführungsgeschwindigkeit (sollte ich die Sache endlich mal zum Laufen bringen) eindeutig ein Vorteil. Irgendwo ist der Wurm drin, ein paar Tage Pause oder Abstand zu dem Programm und vielleicht sehe ich dann das was ich bisher immer übersehe....
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#7

AW: Zugriffsverletzung

  Alt 26. Jul 2016, 13:34
Ich glaub ich werd welk...


Aber leider: nach dem 62zigsten Aufruf der Funktion ist Ende. Genau der selbe Fehler wegen Schutzverletzung.
Dann ist die DLL augenscheinlich nicht schuld.
Bereichsprüfung sehe ich soeben in einem anderen Post. Ist das eine Compileroption?
Jo

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Bambini
(Gast)

n/a Beiträge
 
#8

AW: Zugriffsverletzung

  Alt 26. Jul 2016, 15:04
Ich glaub ich werd welk...
Aber leider: nach dem 62zigsten Aufruf der Funktion ist Ende. Genau der selbe Fehler wegen Schutzverletzung.
Dann ist die DLL augenscheinlich nicht schuld.
Vielleicht gibt die DLL die übergebenen Variablen bereits frei. Daher raucht die Delphi SysFreeMem() Funktion beim Aufräumen der Routine.
Erzeuge doch mal die AnsiString Variable mit New(), damit Delphi diese nicht mehr aufräumen kann.
Damit entstehen zwar Delphi Memory Leaks, aber evtl. hören die AV auf.
  Mit Zitat antworten Zitat
schand99

Registriert seit: 7. Nov 2013
Ort: Südtirol
43 Beiträge
 
Delphi XE8 Enterprise
 
#9

AW: Zugriffsverletzung

  Alt 27. Jul 2016, 08:05
Rätsel gelöst, ich hatte immer die DLL in Verdacht, da Anfangs in einer Funktion am End; der Fehler ausgelöst wurde. Durch Umbau von mehreren Berechnungsfunktionen welche Berechnungen aus der DLL benötigten, habe ich dann entdeckt, dass die Freigabe von dynamischen Array's am Ende einer Funktion die Ursache für die Schutzverletzung war. Diese Freigabe erfolgt normalerweise automatisch am End; durch manuelles SetLenght(Variable, 0) konnte ich das Problem genauer einkreisen. Zwei dynamische Array's waren noch ok, ab dem dritten gibt es die Schutzverletzung. Ich verstehe zwar nicht warum das so ist, habe zur Zeit aber nicht die Geduld dem auf den Grund zu gehen. Umstellen auf statische Array's war die Lösung.

Tut mir leid dass einige von Euch über meine (falsche) Vermutung zur Fehlerquelle gegrübelt haben,

Gruß
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

AW: Zugriffsverletzung

  Alt 27. Jul 2016, 08:09
Bin mir ziemlich sicher, dass es nicht an der Tatsache lag dass du dynamische Arrays benutzt hast.
Garantiert hast du irgendwo über die Grenzen einer deiner dyn. Arrays geschrieben (oder unter die Grenzen).

Dass es mit statischen Arrays geht ist vielleicht nur Zufall oder du hast "aus Versehen" eine Größe gewählt die deinen Fehler "verschwinden" lässt.
(Das heißt nicht, dass er weg ist!)
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz