Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Zugriffsverletzung (https://www.delphipraxis.net/189808-zugriffsverletzung.html)

schand99 25. Jul 2016 09:29

Delphi-Version: 5

Zugriffsverletzung
 
Hallo liebe Entwickler,

ich habe ein Problem mit Zugriffsverletzungen beim Aufrufen von Funktionen aus einer DLL. Die DLL "ref_calc32.dll" dient zum Berechnen von Stoffwertdaten von Kältemitteln, eine Dokumentation zu der DLL habe ich leider nicht. Nur ein Quellcodebeispiel geschrieben mit VB 6.0
Daraus konnte ich mir mit viel Probieren die Funktionen der DLL in Delphi einbinden

Zum Beispiel:
Delphi-Quellcode:
Function S_vs(ref: PAnsiChar; t, P: Double; var vs: Double): Boolean; stdcall; external DllName;
  Function S_t_d(ref: PAnsiChar; P: Double; var T_d: Double): Boolean; stdcall; external DllName;
 usw.
Zusätzlich habe ich alle DLL-Aufrufe in eine einzelne Funktion gepackt, um Probleme mit Variablen weitestgehend zu vermeiden.

Delphi-Quellcode:
Function UDllCall(FType, FName: String; TKM, XVar: Double): Double;
 Var
  Temp, res: Double;
  Refr: PAnsiChar;
  Erg: Boolean;
Begin
   //GetMem(Refr, 16);
   Temp := 273.15 + TKM;
   // Berechnen der Stoffwerte
   if FType = 'R404A' then
      Refr := PAnsiChar('r404a')
   else if FType ='R407C' then
      Refr := PAnsiChar('r407c')
   else if FType ='R134A' then
      Refr := PAnsiChar('r134a')
   else if FType ='R410A' then
      Refr := PAnsiChar('r410a')
   else if FType ='R507' then
      Refr := PAnsiChar('r507')
   else if FType ='R22' then
      Refr := PAnsiChar('r22');

   if Uppercase(FName) = 'S_TC' then
      Begin
         erg := S_tc(Refr, res);
      End;

   // usw, usw, ...

   Result := res;

End;
Allerdings bleibt ein Problem bestehen: eine Schutzverletzung. Diese tritt erst beim 62. Aufruf der Funktion auf. Und zwar nach dem 'end;' und betrifft die Freigabe von reserviertem Speicher. Ich vermute einen Zusammenhang mit der Variablen "Refr" vom Typ PAnsiChar. Ich habe auch schon versucht mit GetMem und FreeMem den für die Variable reservierten Speicherbereich zu reservieren und freizugeben. Alles ohne Erfolg.
Hat vielleicht jemand von Euch Delphiprofis einen Tipp?

schon mal vielen Dank,
Andreas

hhcm 25. Jul 2016 09:49

AW: Zugriffsverletzung
 
Und was ist, wenn das if else if konstrukt nicht zustimmt?
Dann wird ein nicht initialisierter Wert übergeben.
Denn ein abschliessendes else oder eine Initialisierung der Variable Refr findet nicht statt.

p80286 25. Jul 2016 10:37

AW: Zugriffsverletzung
 
Wenn ich mich nicht verlesen habe sollte ein simples
Delphi-Quellcode:
LowerCase
bzw. sein entsprechendes Pendant dieses
Delphi-Quellcode:
If..else if..else if
- Monstrum ersetzen können.

Und ansonsten frag mal den Debugger wo es da ein Problem gibt [F7] sollte da sehr hilfreich sein.

Gruß
K-H

baumina 25. Jul 2016 10:57

AW: Zugriffsverletzung
 
Vielleicht hilfts ja : http://www.studfiles.ru/preview/3378435/

ConnorMcLeod 25. Jul 2016 11:02

AW: Zugriffsverletzung
 
Gib mal die Parameter in eine Log-Datei aus und prüfe dort, ob das Erwartete übergeben wird.

schand99 25. Jul 2016 12:03

AW: Zugriffsverletzung
 
Schon mal Danke für die Hinweise.

Es ist sichergestellt, dass 'Refr' niemals leer ist. 'FType' enthält immer den Name des Kältemittels, das wird schon vor dem Aufrufen der Funktion sichergestellt.
Das mit dem if... else if... sieht nicht schön aus und es macht für die DLL auch keinen Unterschied ob Groß- oder Kleinbuchstaben übergeben werden. Allerdings, und das ist auch etwas was ich nicht verstehe, wenn ich der Pointer-Variablen "Refr" unter Verwendung von Refr := PAnsiChar(FType) den String zuweise, dann funktioniert die DLL nicht, gibt immer 0 zurück.

schand99 25. Jul 2016 12:22

AW: Zugriffsverletzung
 
Der Fehler wird in "function SysFreeMem(P: Pointer): Integer" aus Getmem.inc ausgelöst.

Delphi-Quellcode:
function SysFreeMem(P: Pointer): Integer;
asm
{$ifdef CPU386}
{---------------32-bit BASM SysFreeMem---------------}
  {On entry:
    eax = P}
  {Get the block header in edx}
  mov edx, [eax - 4]
  {Is it a small block in use?}
  test dl, IsFreeBlockFlag + IsMediumBlockFlag + IsLargeBlockFlag
  {Save the pointer in ecx}
  mov ecx, eax
  {Save ebx}
  push ebx
  {Get the IsMultiThread variable in bl}
  mov bl, IsMultiThread
  {Is it a small block that is in use?}
  jnz @NotSmallBlockInUse
  {Do we need to lock the block type?}
  test bl, bl
  {Get the small block type in ebx}
  mov ebx, TSmallBlockPoolHeader[edx].BlockType
in dem letzten Befehl mov ebx, TSmallBlockPool... stürzt das Programm ab. Deshalb hatte ich schon mit GetMem und FreeMem versucht, den Platz für den Pointer 'Refr' zu reservieren und manuell wieder freizugeben.
Könnte es sein, dass die 32 Bit DLL auf einem 64 Bit Sytem nicht so funktioniert wie sie soll? Als Zielplattform habe ich zwar Win32 eingestellt, aber man weiß ja nie...

Luckie 25. Jul 2016 13:45

AW: Zugriffsverletzung
 
Werden die Aufrufkonventionen der DLL Funktion beachtet? Irgendwer versucht da aufzuräumen, obwohl wohl schon alles aufgeräumt ist.

schand99 25. Jul 2016 16:14

AW: Zugriffsverletzung
 
Zitat:

Zitat von Luckie (Beitrag 1343296)
Werden die Aufrufkonventionen der DLL Funktion beachtet?

Ja, im Rahmen dessen was die verfügbaren Dokus hergeben. Also das 17 Jahre alte PDF aus Russland und der VB6-Quellcode. Habe auch schon sehr viele andere Konventionen ausprobiert. Ergebnisse aus der DLL gibt es nur dann, wenn die Konventionen aus meinem ersten Post verwendet werden.
Auf dem alten PDF ist eine Telefonnummer zu finden, die könnte möglicherweise geholfen haben. Es wird sich zeigen, ob die neuen Eigentümer der ref_calc32.dll eine aktuelle Version der DLL samt Doku rausrücken :-D

hoika 25. Jul 2016 22:08

AW: Zugriffsverletzung
 
Hallo,
also nach dem hier ist es nicht Boolean, sondern WordBool.

k.A., ob das jetzt das gleiche ist.

http://www.studfiles.ru/preview/3378442/


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:16 Uhr.
Seite 1 von 3  1 23      

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