Autor |
Beitrag |
Bronstein
      
Beiträge: 578
Erhaltene Danke: 1
WIN XP
Delphi 6 / Delphi 2006 / Delphi XE
|
Verfasst: So 29.11.09 07:50
Hallo,
ich habe ein Problem beim dynamischen einbinden einer DLL.
Bekomme immer den Fehler:
Project Project1.exe raised exception class EStringListError with message 'List index out of bounds (-1)'. Process stopped. Use Step or Run to continue.
Und zwar in der Funktion "GetUmruestDauer" in der Zeile 89 "XML := FarProc(pChar(tmpVon), pChar(tmpNach));"
Wie man bei der Funktion "GetUmruestDauer" in der Zeile 75 sieht, rufe ich die Funktion auch mal auf wo ich die DLL fest eingebunden habe, doch da bekomme ich keinen Fehler.
Deshalb liegt es ja nicht an der DLL, was mache ich beim dynamischen einbinden aber falsch?
Das dynamische einbinden der Funktion "GetRuestungPfad" funktioniert doch auch (Zeile 49) und bei "GetUmruestDauer" mache ich doch nichts anderes!
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: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ActiveX, XMLDOC, XMLIntf;
type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private public end;
var Form1: TForm1;
implementation
function DLL_GetUmruestung(RuestungVon, RuestungNach: Pchar): PChar; stdcall; external 'test.dll' name 'GetUmruestung';
{$R *.dfm}
function GetPfadRuestung(DLLName, Linie, Ruestung: String): PChar; type TGetRuestungPfad = function(Linie, Ruestung: Pchar): PChar; var hDLL: THandle; iRes: integer; FarProc: TGetRuestungPfad; sDLLPath, XML: PChar; xmlDocTaktZeit: IXmlDocument; tmpStr: String; begin sDLLPath := pChar(ExtractFilePath(ParamStr(0)) + ''+DLLName); hDLL := LoadLibrary(sDLLPath); if hDLL = 0 then
else begin try FarProc := GetProcAddress(hDLL, 'GetRuestungPfad'); if Assigned(FarProc) then begin XML := FarProc(pChar(Linie), pChar(Ruestung)); xmlDocTaktZeit := LoadXMLData(XML); tmpStr := xmlDocTaktZeit.DocumentElement.ChildNodes['Ruestung'].NodeValue + '\'; result := PChar(tmpStr); end; except
end; end; FreeLibrary(hDLL); end;
function GetUmruestDauer(DLLName, Linie, RuestungVon, RuestungNach: PChar): Integer; type TGetUmruestung = function(RuestungVon, RuestungNach: Pchar): PChar; var hDLL: THandle; iRes: integer; FarProc: TGetUmruestung; sDLLPath, XML, tmpStr: PChar; xmlDocTaktZeit: IXmlDocument; tmpVon, tmpNach: String; begin CoInitialize(nil); tmpVon := GetPfadRuestung(DLLName, Linie, RuestungVon); tmpNach := GetPfadRuestung(DLLName, Linie, RuestungNach); XML := DLL_GetUmruestung(pChar(tmpVon), pChar(tmpNach)); ShowMessage(XML);
sDLLPath := pChar(ExtractFilePath(ParamStr(0)) + ''+DLLName); hDLL := LoadLibrary(sDLLPath); if hDLL = 0 then
else begin try FarProc := GetProcAddress(hDLL, 'GetUmruestung'); if Assigned(FarProc) then begin CoInitialize(nil); XML := FarProc(pChar(tmpVon), pChar(tmpNach));
xmlDocTaktZeit := LoadXMLData(XML); ShowMessage(XML); end; except
end; end; FreeLibrary(hDLL); end;
procedure TForm1.FormCreate(Sender: TObject); var DLLName: String; begin DLLName := 'test.dll'; GetUmruestDauer(Pchar(DllName), pChar('Linie_1'), pChar('B_980_050_1'), pChar('B_980_050_2')); end;
end. | Moderiert von Narses: Topic aus VCL (Visual Component Library) verschoben am So 29.11.2009 um 12:39
_________________ Es gibt keine dummen Fragen nur dumme Antworten!!!
|
|
Boldar
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: So 29.11.09 15:19
Soweit ich weiss, muss man bei Loadlibrary nur den Namen und nicht den Pfad angeben...
Ausserdem ist sowas:
Delphi-Quelltext 1: 2: 3:
| if hdll = 0 then else ... |
Absolut schlechter Stil. Besser so:
Delphi-Quelltext
|
|
Bronstein 
      
Beiträge: 578
Erhaltene Danke: 1
WIN XP
Delphi 6 / Delphi 2006 / Delphi XE
|
Verfasst: So 29.11.09 18:35
Wenn ich nur den DLL Name angebe bekomme ich den selben Fehler, daran liegt es also auch nicht!
Delphi-Quelltext 1:
| hDLL := LoadLibrary(DLLName); |
_________________ Es gibt keine dummen Fragen nur dumme Antworten!!!
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 29.11.09 18:49
Der Unterschied ist, dass du stdcall nicht bei der Deklaration angegeben hast. Dementsprechend werden die Parameter auch entsprechend anders übergeben, so dass das nicht zusammenpasst, wenn in der DLL diese Konvention angegeben ist.
Generell: Ist die DLL auch von dir? Dann debugge die doch einfach, denn da du in dem geposteten Quelltext keine TStringList benutzt, muss der Fehler ja innerhalb der DLL auftreten.
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 29.11.09 19:05
|
|
Boldar
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: So 29.11.09 21:37
Weil er erst im Windows-Verzeichnis sucht, dann im %path% und dann im Arbeitsverzeichnis (dachte ich bisher). Bei der statischen Einbindung ist das doch auch so, und ich wollte auch immer schon bei meinen Projecten die dll's in Unterordner packen, aber das hat nie funktioniert.
Aber wenn du das so sagst, war mein Fehler bestimmt wo anders...
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 29.11.09 22:31
Ich habe schon öfter die DLLs in Unterverzeichnisse gelegt, wie bei anderen Programmen ja auch. Insbesondere bei meinem größten Projekt mit ca. 50 DLLs wäre das sonst sehr unübersichtlich geworden.
Was die Suche angeht hast du wohl Recht, aber das Arbeitsverzeichnis ist ja nicht unbedingt das der Exe, insofern bringt das wenig.
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 29.11.09 23:41
Boldar hat folgendes geschrieben : | Weil er erst im Windows-Verzeichnis sucht, dann im %path% und dann im Arbeitsverzeichnis (dachte ich bisher). |
Und wenn ich die DLL in eine Unterverzeichnis des Programms lege? Und das Arbeitsverzeichnis kann irgend ein verzeichnis sein, aber nicht unbedingt das Programmverzeichnis. Und was ist, wenn es mehrere DLLs mit gleichen Namen gibt?
|
|
|