Entwickler-Ecke

Sonstiges (Delphi) - Seltsame Exception


Bronstein - Di 05.07.16 08:36
Titel: Seltsame Exception
Vielleicht sieht von euch jemand wo der Fehler liegen könnte:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
procedure TfrmAuswertung.Button20Click(Sender: TObject);
type
  TGetStueckzahlDetail = function (StartDatum: TDateTime; Linie, Leiterplatte: PAnsiChar; Taktung: Integer): PAnsiChar; stdcall;
  TGetStueckzahlZeitraum = function(StartDatum, EndeDatum: TDateTime; Linie: PAnsiChar; SchichtTrennung:Boolean=false; LetzteMaschine:Boolean=TRUE; Transportspur:Integer=1): PAnsiChar; stdcall;
var
  hDLL: THandle; // Handle zur DLL
  FarProc: TGetStueckzahlZeitraum;
  XML: PAnsiChar;

  FarProc2: TGetStueckzahlDetail;
  XML2: PAnsiChar;

  xmlDocStueck, xmlDocStueckDetail: IXmlDocument;
  AdoQuery: TAdoQuery;
  i, z: Integer;
  tmpDatum, Start, Ende: TDateTime;
  sDLLPath: PChar;
  Variante: String;
begin
  AdoQuery := TAdoQuery.Create(nil);
  AdoQuery.ConnectionString := frmMain.AdoConnection;

  AdoQuery.SQL.Clear;
  AdoQuery.SQL.Add('SELECT * FROM PLATZ WHERE PLATZ_ID = ' + pString(AdvComboBox11.Items.Objects[AdvComboBox11.ItemIndex])^);
  AdoQuery.Active := true;

  Series13.Clear;
  sDLLPath := pChar(ExtractFilePath(ParamStr(0)) + ''+AdoQuery.FieldByName('DLL_NAME').AsString);
  hDLL := LoadLibrary(sDLLPath);
  if hDLL = 0 then
    //Form1.Statusmeldung('Error', DLLName + ' konnte nicht geladen')
  else
  begin
    try
      FarProc := GetProcAddress(hDLL, 'GetStueckzahlZeitraum');
      if Assigned(FarProc) then
      begin
        XML := FarProc(StartOfTheDay(AdvDateTimePicker15.DateTime), EndOfTheDay(AdvDateTimePicker16.DateTime), PAnsiChar(AnsiString(AdoQuery.FieldByName('ALIASNAME').AsString)), true, true);
        XMLFreigeben(AdoQuery.FieldByName('DLL_NAME').AsString);
        if (XML <> 'Error'and (XML <> ''then
        begin
          xmlDocStueck := LoadXMLData(XML);
          i := xmlDocStueck.DocumentElement.ChildNodes.Count-1;
          while i >= 0 do
          begin
            FarProc2 := GetProcAddress(hDLL, 'GetStueckzahlDetail');
            if Assigned(FarProc2) then
            begin
              Variante := xmlDocStueck.DocumentElement.ChildNodes[i].ChildNodes['Stueckliste'].NodeValue;
              Start := StrToDateTime(xmlDocStueck.DocumentElement.ChildNodes[i].ChildNodes['StartZeit'].NodeValue);
              XML2 := FarProc2(Start, PAnsiChar(AnsiString(AdoQuery.FieldByName('ALIASNAME').AsString)), PAnsiChar(AnsiString(Variante)), 10);
              xmlDocStueckDetail := LoadXMLData(XML2);
              for z:=0 to xmlDocStueckDetail.DocumentElement.ChildNodes.Count-1  do
              begin
                if xmlDocStueckDetail.DocumentElement.ChildNodes[z].ChildNodes['Pass'].NodeValue > 0 then
                begin
                  try
                    tmpDatum := StrToDateTime(xmlDocStueckDetail.DocumentElement.ChildNodes[z].ChildNodes['Datum'].NodeValue);
                  except
                  on e: exception do
                    ShowMessage(e.Message);
                  end;
                  Series13.AddGanttColor(tmpDatum, incMinute(tmpDatum, 10), 1'', clLime);
                  Application.ProcessMessages;
                end;


              end;
              XMLFreigeben(AdoQuery.FieldByName('DLL_NAME').AsString);
              XML2 := nil;
            end;
            //break;
            i := i-1;
          end;
        end;
      end;
      Application.ProcessMessages;
      XMLFreigeben(AdoQuery.FieldByName('DLL_NAME').AsString);
      Application.ProcessMessages;
      FreeLibrary(hDLL);
      XML := nil;
      hDLL := 0;

      Application.ProcessMessages;
    except
      on e: exception do
        ShowMessage(e.Message);
    end;
  end;

  AdoQuery.Free;
end;


Bekomme folgenden Fehler wenn die Funktion komplett durchgelaufen ist:
---------------------------
Benachrichtigung über Debugger-Problem
---------------------------
In Projekt xxx.exe trat ein Problem mit folgender Meldung auf: 'access violation at 0x74becb49: read of address 0x00000000'. Prozess angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK
---------------------------


OlafSt - Di 05.07.16 12:24

Die Adresse 0x74... deutet auf eine DLL hin, in der es rummst. Die Delphi-Anwendung selbst liegt, wie alle Anwendungen auch, im 0x4.... Bereich, seltener im 0x5...-Bereich.

Die Tatsache, das es in der DLL kracht, deutet auf ein Problem mit der dynamisch zugeladenen DLL hin. Wenn es beim Verlassen der Prozdur passiert, ist fast immer der Stack zerstört worden. Dies wiederum ist, zusammen mit der DLL, ein Hinweis auf ein Problem mit den Parametern für die DLL (genauer: dem Aufräumen der Params vom Stack).

Ich tippe auf unterschiedliche Calling Conventions zwischen DLL und Hauptprogramm. Da in der EXE ein stdcall angegeben wurde, wird das in der DLL vermutlich anders angegeben sein (cdecl, pascal o.ä.)


Bronstein - Mi 06.07.16 12:41

Hallo,
das sind die Deklarationen der DLL:


Delphi-Quelltext
1:
2:
3:
function GetStueckzahlDetail(StartDatum: TDateTime; Linie, Leiterplatte: PAnsiChar; Taktung: Integer; Transportspur:Integer=1): PAnsiChar; stdcall;

function GetStueckzahlZeitraum(StartDatum, EndeDatum: TDateTime; Linie: PAnsiChar; SchichtTrennung:Boolean=false; LetzteMaschine:Boolean=TRUE; Transportspur:Integer=1): PAnsiChar; stdcall;



Hilft diese Meldung vllt. noch weiter:
00408B82 F0FF4AF8 lock dec dword ptr [edx-$08]