Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Fehler "access violation" - keine Ahnung, warum... (https://www.delphipraxis.net/169819-fehler-access-violation-keine-ahnung-warum.html)

Pow3rus3r 14. Aug 2012 11:40

Fehler "access violation" - keine Ahnung, warum...
 
Hallo zusammen,

ich habe eine Delphi Prozedur, die mir nach der Abarbeitung (nachdem der letzte Befehl ausgeführt wurde) eine "access violation at 0x004070e8: write at address 0x004abefc" rauswirft.

Ich habe allerdings keine Ahnung, wo der Fehler her kommt (da er nach der Ausführung auftritt). So langsam bin ich echt am verzweifeln.

Verstehe ich das richtig, dass irgendwo versucht wird, auf einen Speicherbereich zu schreiben, der nicht frei/unbekannt ist?

Danke und Gruß
Thomas

Klaus01 14. Aug 2012 11:43

AW: Fehler "access violation" - keine Ahnung, warum...
 
.. es mag ja sein, dass Du den Code auswendig kennst
Wir jedoch nicht.

Grüße
Klaus

Pow3rus3r 14. Aug 2012 11:54

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von Klaus01 (Beitrag 1178171)
.. es mag ja sein, dass Du den Code auswendig kennst
Wir jedoch nicht.

Grüße
Klaus

Ich weiß nicht, ob der Code hier hilfreich ist, da die Prozedur auf einige öffentliche Variablen zugreift und der gesamte Code gute 3000 Zeilen hat.

Hier mal die Prozedur, die den fehler rauswirft:
Delphi-Quellcode:
procedure TForm1.btnstartmanipulationsClick(Sender: TObject);
var
  i: integer;
  y: integer;
  slFile: TStringlist;

begin
  { Verbindungsaufbau }
  return := COM_TcpOpen(zeiger, ipAddress, port);
  { evtl. laufende Manipulationen stoppen und Stringlist initialisieren }
  return := COM_StopRbsManipulationReq(zeiger);
  slFile := TStringList.Create;
  try
    slFile.LoadFromFile(strfilename);

    y := 0;
    { Manipulationen an Box übertragen }
    for i := low(man1) to high(man1) do
    begin
      SetLength(manipulationlist, y+1);
      manipulationlist[y].TriggerType := strtoint(slFile[man1[i].zeile + 3]);
      manipulationlist[y].TriggerMode := strtoint(slFile[man1[i].zeile + 4])+1;
      manipulationlist[y].TriggerSource := strtoint(slFile[man1[i].zeile + 5]);
      manipulationlist[y].TriggerValue := strtoint(slFile[man1[i].zeile + 6]);
      manipulationlist[y].TriggerHysterese := strtoint(slFile[man1[i].zeile + 7]);
      manipulationlist[y].DelayValue := strtoint(slFile[man1[i].zeile + 8]);
      manipulationlist[y].DelayType := strtoint(slFile[man1[i].zeile + 9]);
      manipulationlist[y].SequenceNumber := strtoint(slFile[man1[i].zeile + 10]);
      manipulationlist[y].ManipulationType := strtoint(slFile[man1[i].zeile + 11]);
      manipulationlist[y].ManipulationDuration := strtoint(slFile[man1[i].zeile + 12]);
      manipulationlist[y].ManipulationDurationType := strtoint(slFile[man1[i].zeile + 13]);
      manipulationlist[y].ManipulationMode := strtoint(slFile[man1[i].zeile + 14]);
      manipulationlist[y].ManipulationTarget := strtoint(slFile[man1[i].zeile + 15]);
      manipulationlist[y].ManipulationTargetValue := 0;
      manipulationlist[y].ManipulationValue1 := strtoint(slFile[man1[i].zeile + 17]);
      manipulationlist[y].ManipulationValue2 := strtoint(slFile[man1[i].zeile + 18]);
      manipulationlist[y].ManipulationValue3 := strtoint(slFile[man1[i].zeile + 19]);

      // Einzelne Signalmanipulation speichern/hochladen zu Box
      return := COM_RbsManipulationReq(zeiger, manipulationlist[y]);
      y := y + 1;
    end;
    // Manipulationen starten
    return := COM_StartRbsManipulationReq(zeiger);
  finally
    slFile.Free;
  end;

end;

Pow3rus3r 14. Aug 2012 11:56

AW: Fehler "access violation" - keine Ahnung, warum...
 
Achja, wenn ich diese zeile auskommentiere, kommt der Fehler nicht:
Delphi-Quellcode:
return := COM_RbsManipulationReq(zeiger, manipulationlist[y]);

sx2008 14. Aug 2012 12:05

AW: Fehler "access violation" - keine Ahnung, warum...
 
Dieser Thread hat einen Vorgänger: c DLL in Delphi einbinden (Prozedureinsprungspunkt nicht gefunden)

Also ganz offensichtlich befüllst du nicht alle Member des Records Manipulationtag.
Dadurch können die nicht-befüllten Member zufällige Werte annehmen, was dann zu einem Fehler in der DLL führen kann.

Bjoerk 14. Aug 2012 12:19

AW: Fehler "access violation" - keine Ahnung, warum...
 
Spendier' der Komponente mal eine manipulationlist.LoadFromFile, dann dürfte der Fehler schneller gefunden werden.

Pow3rus3r 14. Aug 2012 12:23

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von sx2008 (Beitrag 1178180)
Dieser Thread hat einen Vorgänger: c DLL in Delphi einbinden (Prozedureinsprungspunkt nicht gefunden)

Also ganz offensichtlich befüllst du nicht alle Member des Records Manipulationtag.
Dadurch können die nicht-befüllten Member zufällige Werte annehmen, was dann zu einem Fehler in der DLL führen kann.

Doch, das Record "Manipulationtag" hat sich mittlerweile geändert. Ich habe den Code nun mal aufs wesentliche zusammengestaucht und nur die beteiligten Funktionen rausgesucht.

Hier ist quasi das komplette projekt drin und der Fehler tritt auch hier auf:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

 type
  Manipulationtag = record
    TriggerType: byte;           ///< Trigger 1: Identify whether the TriggerValue is an address or a value (0: trigger not active; 1: trigger at value; 2: trigger at address; 3: trigger at value cyclic; 4: trigger at address cyclic)
    TriggerMode: byte;           ///< Trigger 1: Identify the trigger mode (1: '=='; 2: '!='; 3: '>'; 4: '<'; 5: '<='; 6: '>='; 7: 'edge')
    TriggerSource: longword;     ///< Trigger 1: The trigger source is the signal which value is used to trigger
    TriggerValue: longword;      ///< Trigger 1: The trigger value to compare with the trigger source value
    TriggerHysterese: longword;  ///< Trigger 1: Trigger hysteresis identify the hysteresis at trigger mode "edge"
    DelayValue: word;              ///< Delay to start the manipulation
    DelayType: byte;               ///< The delay value type (0: events since sequence start; 1: cycles since sequence start; 2: ms since sequence start; 3: events since last manipulation; 4: cycles since last manipulation; 5: ms since last manipulation)
    SequenceNumber: byte;          ///< Identify the position of this manipulation in a sequence. For trigger manipulations the sequence number is '0'
    ManipulationType: byte;        ///< Identify the manipulation type (1: loss; 2: offset; 3: value; 4: factor; 5: drift - from n to m in p steps ; 6: ramp - from n to m in p steps ; 7: disable manipulation; 8: freeze; 9: ramp with hold final value - from n to m in p steps; 10: drift with hold final value - from n to m in p steps; 11: factor linear; 12: offset negative)
    ManipulationDuration: word;    ///< Identify the duration of a manipulation (0 means infinite duration)
    ManipulationDurationType: byte; ///< Identify the unit of the duration (0: duration is given in events; 1: duration is given in cycles; 1: duration is given in ms)
    ManipulationMode: byte;        ///< Identify the manipulation target type (1: frame; 2: PDU; 3: signal group; 4: signal; 5: ECU)
    ManipulationTarget: longword;  ///< Identify the address or identifier of the element to manipulate
    ManipulationTargetValue: word; ///< Sets a parameter for the manipulated target (e.g. ecu index number )
    ManipulationValue1: longword;  ///< The value one of the manipulation (n)
    ManipulationValue2: longword;  ///< The value two of the manipulation (m)
    ManipulationSteps: word;  ///< The value three of the manipulation (p)
  end;

type
  TForm1 = class(TForm)
    btnconnect: TButton;
    btndisconnect: TButton;
    btngetversion: TButton;
    lblstatus: TLabel;
    btnclose: TButton;
    btnstartmanipulation: TButton;
    btnstopmanipulation: TButton;
    btnchangemanipulation: TButton;
    txtvalue: TEdit;
    btnreadfile: TButton;
    Button1: TButton;
    procedure btnconnectClick(Sender: TObject);
    procedure btndisconnectClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure btnstartmanipulationClick(Sender: TObject);
    procedure btnstopmanipulationClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
  var
    { Public-Deklarationen }
    zeiger:Pointer;
    return:NativeUInt;
    ipAddress:ANSIString;
    port:smallint;
    tagmanipulation: Manipulationtag;
    tagmanipulation2: Manipulationtag;
    boolconnected: boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
function COM_TcpOpen(var zeiger:Pointer; ipAddress:AnsiString; port:smallint): NativeUInt; stdcall; external 'HwCom.dll';
function COM_Close(zeiger:Pointer):NativeUInt; stdcall; external 'HwCom.dll';
function COM_RbsManipulationReq(zeiger:Pointer; manipulation:Manipulationtag): NativeUInt; stdcall; external 'HwCom.dll' name '_COM_RbsManipulationReq@112';
function COM_StartRbsManipulationReq(zeiger:Pointer): NativeUInt; stdcall; external 'HwCom.dll' name '_COM_StartRbsManipulationReq@4';
function COM_StopRbsManipulationReq(zeiger:Pointer): NativeUInt; stdcall; external 'HwCom.dll' name '_COM_StopRbsManipulationReq@4';

{ Programmstart: Variablen initialisieren }
procedure TForm1.FormCreate(Sender: TObject);
  begin
     lblstatus.Caption := '';
     ipAddress:='192.168.1.15';
     port := 1500;
     new(zeiger);
     zeiger := NIL;
     boolconnected := false;

      tagmanipulation.TriggerType:=0;
      tagmanipulation.TriggerMode:=1;
      tagmanipulation.TriggerSource:=0;
      tagmanipulation.TriggerValue:=0;
      tagmanipulation.TriggerHysterese:=0;

      tagmanipulation.DelayValue:=0;
      tagmanipulation.DelayType:=0;

      tagmanipulation.SequenceNumber:=0;
      tagmanipulation.ManipulationType:=3;
      tagmanipulation.ManipulationDuration:=0;
      tagmanipulation.ManipulationDurationType:=1;
      tagmanipulation.ManipulationMode:=4;
      tagmanipulation.ManipulationTarget:=123456;
      tagmanipulation.ManipulationTargetValue:=0;

      tagmanipulation.ManipulationValue1:=1000;
      tagmanipulation.ManipulationValue2:=0;
      tagmanipulation.ManipulationSteps:=0;
  end;

{ Signal manipulieren }
procedure TForm1.btnstartmanipulationClick(Sender: TObject);
  begin
    return := COM_RbsManipulationReq(zeiger, tagmanipulation);
    return := COM_StartRbsManipulationReq(zeiger);
  end;

{ Manipulation stoppen }
procedure TForm1.btnstopmanipulationClick(Sender: TObject);
  begin
    return := COM_StopRbsManipulationReq(zeiger);
  end;

{ Verbindungsaufbau }
procedure TForm1.btnconnectClick(Sender: TObject);
  begin
    { Verbindungsaufbau zu Flexcon midget }
    return := COM_TcpOpen(zeiger, ipAddress, port);
    boolconnected := true;
  end;

{ Verbindungsabbau }
procedure TForm1.btndisconnectClick(Sender: TObject);
  begin
    { Verbindungsabbau }
    return := COM_Close(zeiger);
    zeiger := NIL;
  end;
end.

DeddyH 14. Aug 2012 12:29

AW: Fehler "access violation" - keine Ahnung, warum...
 
Bei diesem Zeiger steig ich nicht durch, bist Du sicher, dass das alles so richtig ist?

Pow3rus3r 14. Aug 2012 12:32

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von DeddyH (Beitrag 1178190)
Bei diesem Zeiger steig ich nicht durch, bist Du sicher, dass das alles so richtig ist?

Der Zeiger wird beim Verbindungsaufbau durch die remote-hardware gefüllt. Über diesen zeiger wird die hardware dann nach dem Verbindungsaufbau angesprochen. Die erfolgreiche Ausführung der remote-Funktionen wird mit dem Returnwert 0 quittiert (und den erhalte ich auch von allen Funktionen).

Das komische ist, dass die komplette Prozedur eigentlich funktioniert (sie tut das, was sie soll). Aber ganz zum Schluss kommt der Fehler und stoppt die weitere Ausführung.

Pow3rus3r 14. Aug 2012 12:35

AW: Fehler "access violation" - keine Ahnung, warum...
 
nach dem Fehler springt Delphi in ein Debug Fenster (CPU).

Dort wird folgendes angezeigt:
004070E8 F0FF4AF8 lock dec dword ptr [edx-$08]

DeddyH 14. Aug 2012 12:57

AW: Fehler "access violation" - keine Ahnung, warum...
 
Kannst Du mir Deinen Gedankengang hier einmal erklären?
Zitat:

Delphi-Quellcode:
new(zeiger);
zeiger := NIL;

Und wird der übergebene Zeiger von der Funktion COM_TcpOpen tatsächlich verändert, oder werden nur die dahinterstehenden Daten befüllt?

himitsu 14. Aug 2012 13:01

AW: Fehler "access violation" - keine Ahnung, warum...
 
Geh mal in die Projektoptionen und aktiviere dort die Bereichsprüfung und eventuell noch die Debug-DCUs.

Pow3rus3r 14. Aug 2012 13:04

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von DeddyH (Beitrag 1178202)
Kannst Du mir Deinen Gedankengang hier einmal erklären?
Zitat:

Delphi-Quellcode:
new(zeiger);
zeiger := NIL;

Und wird der übergebene Zeiger von der Funktion COM_TcpOpen tatsächlich verändert, oder werden nur die dahinterstehenden Daten befüllt?

Der Zeiger wird eigentlich nur auf NIL gesetzt, damit ich sehen kann, ob er initialisiert wurde (von der Hardware) oder nicht. Sonst hätte der neue Zeiger schon von beginn an irgendeinen Wert und es wäre nicht ersichtlich, ob der wert von der Hardware zugewiesen wurde oder ob er einfach nur ein Zufallswert ist, der bei der zeigererzeugung zugewiesen wurde.

Die Funktion COM_TCpOpen weist dem Zeiger einen Wert zu (vorher NIL, nachher ein hardwarespezifischer Wert).

Pow3rus3r 14. Aug 2012 13:07

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von himitsu (Beitrag 1178207)
Geh mal in die Projektoptionen und aktiviere dort die Bereichsprüfung und eventuell noch die Debug-DCUs.

Das bringt mir dann folgende Meldung im Debugger:
Code:
   LOCK DEC    [EDX-skew].StrRec.refCnt       { threadsafe dec refCount      }
Und diese Meldung befindet sich in dieser Prozedur:
Code:
procedure _UStrArrayClr(var StrArray; Count: Integer);
{$IF not defined(CPU386)}
var
  P: Pointer;
begin
  P := @StrArray;
  while Count > 0 do
  begin
    _UStrClr(P^);
    Dec(Count);
    Inc(NativeInt(P), SizeOf(Pointer));
  end;
end;
{$ELSE}
asm
        { ->   EAX pointer to str     }
        {       EDX cnt                }

        {$IFDEF ALIGN_STACK}
        SUB    ESP,4
        {$ENDIF ALIGN_STACK}
        PUSH   EBX
        PUSH   ESI
        MOV    EBX,EAX
        MOV    ESI,EDX

@@loop:
        MOV    EDX,[EBX]                      { fetch str                    }
        TEST   EDX,EDX                        { if nil, nothing to do        }
        JE     @@doneEntry
        MOV    dword ptr [EBX],0               { clear str                    }
        MOV    ECX,[EDX-skew].StrRec.refCnt   { fetch refCnt                 }
        DEC    ECX                            { if < 0: literal str          }
        JL     @@doneEntry
   LOCK DEC    [EDX-skew].StrRec.refCnt       { threadsafe dec refCount      }
        JNE    @@doneEntry
        LEA    EAX,[EDX-skew]                 { if refCnt now zero, deallocate}
        CALL   _FreeMem
@@doneEntry:
        ADD    EBX,4
        DEC    ESI
        JNE    @@loop

        POP    ESI
        POP    EBX
        {$IFDEF ALIGN_STACK}
        ADD    ESP,4
        {$ENDIF ALIGN_STACK}
end;
{$IFEND}
Das sind für mich allerdings alle böhmische Dörfer ;)

EWeiss 14. Aug 2012 13:08

AW: Fehler "access violation" - keine Ahnung, warum...
 
Bist sicher das der Zeiger identisch ist mit dem der als rückgabe bei open erzeut wird?
Hatte auch mal ein probleme das ein zeiger aus unerklärlichen gründen gelöscht bzw.. nicht gleich war.

gruss

DeddyH 14. Aug 2012 13:13

AW: Fehler "access violation" - keine Ahnung, warum...
 
Wie sieht denn das Headerfile zu der DLL aus? Eigentlich gibt es ja nur 2 Möglichkeiten:
- die DLL fordert den Speicher an, befüllt ihn und gibt den Zeiger zurück
- die DLL erwartet einen Zeiger auf selbst angeforderten Speicher und befüllt diesen

Auf jeden Fall vermute ich, dass das ein Zeiger auf den Record sein soll und kein untypisierter. Die Kombination von New() und anschließendem NULLen macht zumindest keinen Sinn.

Pow3rus3r 14. Aug 2012 13:25

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von DeddyH (Beitrag 1178216)
Wie sieht denn das Headerfile zu der DLL aus? Eigentlich gibt es ja nur 2 Möglichkeiten:
- die DLL fordert den Speicher an, befüllt ihn und gibt den Zeiger zurück
- die DLL erwartet einen Zeiger auf selbst angeforderten Speicher und befüllt diesen

Auf jeden Fall vermute ich, dass das ein Zeiger auf den Record sein soll und kein untypisierter. Die Kombination von New() und anschließendem NULLen macht zumindest keinen Sinn.

Der Zeiger müsste eigentlich stimmen, denn mit falschem Zeiger macht die hardware garnichts bei Aufruf der entsprechenden Funktionen. Aber nach Aufruf der Funktionen startet die hardware wie gewünscht eine Signalmanipulation. Auch dürfte die Funktion sonst keine 0 als Rückgabewert (Ausführung ok) liefern.

sx2008 14. Aug 2012 13:28

AW: Fehler "access violation" - keine Ahnung, warum...
 
Ich würde empfehlen erst mal richtig aufzuräumen.
Dazu gehört dass das Record TManipulationtag sowie die Deklarationen für function COM_TcpOpen usw. in eine eigene Unit verschoben werden.

Alles was zur Ansteuerung der DLL benötigt wird muss in eine eigene Unit gepackt werden.
Alles andere wäre unprofessionell.

Delphi-Quellcode:
unit HwCom;
{
Hier Doku über die DLL (Hersteller, Zweck, Webseite,...) rein

}


interface

uses
  Windows;

 type
  TManipulationtag = record
    TriggerType: byte; ///< Trigger 1: Identify whether the TriggerValue is an address or a value (0: trigger not active; 1:  
  // ...
  end;

function COM_TcpOpen(var zeiger:Pointer; ipAddress:AnsiString; port:smallint): NativeUInt; stdcall;
...

implementation

const HWCOM_DLL = 'HwCom.dll';

function COM_TcpOpen(var zeiger:Pointer; ipAddress:AnsiString; port:smallint): NativeUInt; stdcall; external HWCOM_DLL;
...

end;
Die Unit HwCom wird dann per Uses in deiner Formularunit eingebunden.
Und dabei fällt mir sogleich ein Problem auf:
Du übergibst den Parameter ipAddress als
Delphi-Quellcode:
AnsiString
. Dieser Datentyp ist aber unter C/C++ unbekannt und dürfte wohl eher ein
Delphi-Quellcode:
PAnsiChar
sein.

Pow3rus3r 14. Aug 2012 13:29

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von EWeiss (Beitrag 1178212)
Bist sicher das der Zeiger identisch ist mit dem der als rückgabe bei open erzeut wird?
Hatte auch mal ein probleme das ein zeiger aus unerklärlichen gründen gelöscht bzw.. nicht gleich war.

gruss

Ja, der Zeigerinhalt ist gleich dem Rückgabewert der TcpOpen Funktion.

himitsu 14. Aug 2012 13:36

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von Pow3rus3r (Beitrag 1178211)
Das sind für mich allerdings alle böhmische Dörfer ;)

Wichtiger wäre an der Stelle, der Stacktrace.
Du weißt jetzt wo es knallt, also beim Freigeben eines String-Arrays, bzw. mehrerer Strings,
aber irgendwer hat ja diese Prozedur aufgerufen und bei dem könnte man nachsehn, was er "genau" freigeben will, also welche Strings/Stringvariablen das sind
und dann hat man einen Anhaltspunkt, wo man eventuell nach der Ursache suchen könnte.

Aber eventuell hast du ja irgendwo Bufferoverrun, welcher zufällig diese Stringvariablen überschreibt.

EWeiss 14. Aug 2012 13:42

AW: Fehler "access violation" - keine Ahnung, warum...
 
Wo kann man die DLL und die C++ Bibliothek/API laden?
Will da mal reinschaun.

gruss

Pow3rus3r 14. Aug 2012 13:48

AW: Fehler "access violation" - keine Ahnung, warum...
 
Die DLL kann ich leider aus Copyrightgründen nicht rausgeben. Zudem habe ich keinen Quellcode der DLL, sondern nur die kompilierte Datei.

EWeiss 14. Aug 2012 13:49

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von Pow3rus3r (Beitrag 1178232)
Die DLL kann ich leider aus Copyrightgründen nicht rausgeben. Zudem habe ich keinen Quellcode der DLL, sondern nur die kompilierte Datei.

Ok Danke ;)
Kein problem.

gruss

DeddyH 14. Aug 2012 13:53

AW: Fehler "access violation" - keine Ahnung, warum...
 
Aber das entsprechende Headerfile kannst Du weitergeben? Oder war da gleich die Schnittstellenunit dabei (es sieht ja nicht danach aus)?

EWeiss 14. Aug 2012 14:08

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von DeddyH (Beitrag 1178234)
Aber das entsprechende Headerfile kannst Du weitergeben? Oder war da gleich die Schnittstellenunit dabei (es sieht ja nicht danach aus)?

Es ist halt sehr unsicher was er da macht.
Er sollte mal prüfen ob stdcall überhaupt für diese DLL in frage kommt.
Selbst dann wenn die Rückgaben stimmen muss es nicht zwangsläufig korrekt sein.

Calling Conventions (Cdecl, and StdCall) (C/C++)

gruss

DeddyH 14. Aug 2012 14:11

AW: Fehler "access violation" - keine Ahnung, warum...
 
Da gibt es Einiges, was mir komisch vorkommt, daher ja meine Frage, ich habe keine Lust zu raten ;)

Pow3rus3r 14. Aug 2012 14:13

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von DeddyH (Beitrag 1178234)
Aber das entsprechende Headerfile kannst Du weitergeben? Oder war da gleich die Schnittstellenunit dabei (es sieht ja nicht danach aus)?

Wie gesagt, ich habe leider keinen Quellcode/Headerdatei zur dll, sondern nur die dll ansich und eine Doku dazu.

Die Doku sagt folgendes für den Pointer, der an die Funktion COM_RbsManipulationReq übergeben wird:
Code:
typedef void *  COM_Handle
  Defines a handle to a PC->Hardware communication object.

DeddyH 14. Aug 2012 14:15

AW: Fehler "access violation" - keine Ahnung, warum...
 
Und was sagt die Doku zu den Funktionen?

Pow3rus3r 14. Aug 2012 14:18

AW: Fehler "access violation" - keine Ahnung, warum...
 
Das komplette Programm ist bis heute Morgen (mit anderem, umfangreicherem Record "Manipulationtag") gelaufen.

Eine andere Firmware auf der manipulationsbox erfordert aber ein abgespecktes Record, da die hardware sonst abstürzt (Funktion überladen).

Ich habe außer dem kürzen des Records also nichts am Quellcode geändert. Seitdem kommt die accessviolation. Wenn ich das Record wieder um die herausgelöschten Felder erweitere, kommt der Fehler nicht mehr.

Pow3rus3r 14. Aug 2012 14:19

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von DeddyH (Beitrag 1178240)
Und was sagt die Doku zu den Funktionen?

Bei der Funktion, die anscheinend das Problem macht, sagt sie folgendes:
Code:
EXPORTDLL COM_RETURN EBEL_API COM_RbsManipulationReq ( COM_Handle handle,
  COM_RbsManipulation manipulation
 )  

Sets a RBS manipulation.

Parameters:
handle Pointer to a handle representing the interface instance.
manipulation contains the RBS manipulation settings.

Returns:
COM_RETURN_OK Function executed successfully.
COM_RETURN_InvalidHandle The handle is not a valid PC HW interface handle.
COM_RETURN_Timeout The hardware is not responding.
else Error code of the called function in the hardware.

DeddyH 14. Aug 2012 14:20

AW: Fehler "access violation" - keine Ahnung, warum...
 
Das hättest Du aber auch ein bisschen früher sagen können. Habe ich die Situation richtig verstanden:
- größerer Record -> Programm läuft, Hardware stürzt ab
- kleinerer Record -> Programm stürzt ab
:?:

EWeiss 14. Aug 2012 14:22

AW: Fehler "access violation" - keine Ahnung, warum...
 
Dann erstelle zwei records und vergleiche auf die Firmware ..

Einen Record in der reihenfolge zu ändern bzw.. zu kürzen ist keine gute Idee
Mach das mal bei meiner DLL dann geht auch nichts mehr.
Ist aber auch logisch oder?

Das hat mich auch gewundert "NativeUInt" = HRESULT in C++

Delphi-Quellcode:
if COM_TcpOpen(zeiger, ipAddress, port) = S_OK then
begin
  ...
end
aber jeder so wie er will.

EDIT:

Sorry: Diese art der Programmierung ist auch unverständlich.

Delphi-Quellcode:
procedure TForm1.btnstartmanipulationClick(Sender: TObject);
   begin
     return := COM_RbsManipulationReq(zeiger, tagmanipulation);
     return := COM_StartRbsManipulationReq(zeiger);
   end;
Du definierst eine Variable return und tust nichts damit
Irgendwo seltsam das ganze.

gruss

p80286 15. Aug 2012 15:28

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zunächst einmal scheint hier ein Mißverständnis über Zeiger/Pointer vor zu liegen.
Ein Zeiger/Pointer enthält NIL oder eine Adresse, die auf einen Speicherbereich zeigt. Der Wert, den der Zeiger enthält, ist vollkommen uninteressant. Von Interesse ist nur der Speicherbereich auf den der Zeiger zeigt. Wenn hier ein paarmal vom Inhalt des Zeigers die Rede war hoffe ich, daß dies eine sprachliche Ungenauigkeit war.
Wie DeddyH schon ausgeführt hat ist
Delphi-Quellcode:

zeiger : pointer;

...

new(zeiger);
vornehm ausgedrückt, Blödsinn.
Delphi-Quellcode:
new(zeiger);
ist nur dann sinnvoll, wenn zeiger als Pointer auf irgendetwas definiert ist. z.B.
Delphi-Quellcode:
tmyrec=record
         wert:integer;
         nix :byte;
       end;
 
zeiger:^tmyrec;
pint :înteger;

...

new(zeiger);
new(pint);
Dann beginnt die Record Definition mit zwei Byte-Werten.
Das könnte nach einem
Delphi-Quellcode:
packed record
verlangen, muß aber nicht. Wäre u.U. aber auch eine Erklärung für das Verhalten.

Gruß
K-H

Pow3rus3r 16. Aug 2012 07:34

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von DeddyH (Beitrag 1178243)
Das hättest Du aber auch ein bisschen früher sagen können. Habe ich die Situation richtig verstanden:
- größerer Record -> Programm läuft, Hardware stürzt ab
- kleinerer Record -> Programm stürzt ab
:?:

So ist es. Bei dem zu großen (ehemals korrekten) Record bekomme ich ein Hardwaretimout als Returnwert und das Programm bringt keinen Fehler.

Bei dem kleineren Record funktioniert die Werteübergabe an die Hardware (und die Hardware setzt den Befehl korrekt um), aber mein Delphi Programm bringt den Fehler.

DeddyH 16. Aug 2012 07:40

AW: Fehler "access violation" - keine Ahnung, warum...
 
Man könnte da jetzt wild herumwuseln (das Schlüsselwort absolute kommt mir da in den Sinn). Aber an Deiner Stelle würde ich zunächst beim Hersteller nachfragen, ob es eine an die neue Firmware angepasste DLL gibt. Anschließend die Firmware-Version erfragen und je nachdem die eine oder andere DLL laden und mit dem passenden Record ansprechen. Das scheint mir noch das Einfachste zu sein.

Pow3rus3r 16. Aug 2012 09:42

AW: Fehler "access violation" - keine Ahnung, warum...
 
Zitat:

Zitat von DeddyH (Beitrag 1178413)
Man könnte da jetzt wild herumwuseln (das Schlüsselwort absolute kommt mir da in den Sinn). Aber an Deiner Stelle würde ich zunächst beim Hersteller nachfragen, ob es eine an die neue Firmware angepasste DLL gibt. Anschließend die Firmware-Version erfragen und je nachdem die eine oder andere DLL laden und mit dem passenden Record ansprechen. Das scheint mir noch das Einfachste zu sein.

Die Anfrage hatte ich gestern schon rausgeschickt. Gerade kam eine Antwort. Die DLL hat sich geändert, natürlich mit anderem Prozedureinsprungspunkt (_COM_RbsManipulationReq@52 statt _COM_RbsManipulationReq@112).

Nun kommt kein Fehler mehr!

Da wäre ich im Leben nicht drauf gekommen. Danke für eure Hilfe! Ihr seid echt mal fit in Delphi!

himitsu 16. Aug 2012 10:23

AW: Fehler "access violation" - keine Ahnung, warum...
 
In C-Sprachen und in den Delphi-BPLs wird im Exportnamen von Funktionen/Prozeduren auch gerne mal die Parameterdeklaration mit aufgenommen.
Bei Delphi-DLLs (wenn man nicht explizit ws nderes angibt) und bei vielen WinAPIs enspricht aber der Exportname dem Prozedurnamen.

Zitat:

Da wäre ich im Leben nicht drauf gekommen
Wie importierst du denn die Prozedur?

Da hätte es doch schon auffallen sollen, daß die Prozedur, unter dem alten Namen, nicht gefunden wird. :gruebel:


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:45 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