| 
| Autor | Beitrag |  
| Bronstein 
          Beiträge: 578
 Erhaltene Danke: 1
 
 WIN XP
 Delphi 6 / Delphi 2006 / Delphi XE
 
 | 
Verfasst: So 29.11.09 06: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! 
 			Moderiert von									| 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.
 |   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 14: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 thenelse
 ...
 |  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 17: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: 19326
 Erhaltene Danke: 1749
 
 W11 x64 (Chrome, Edge)
 Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
 
 | 
Verfasst: So 29.11.09 17: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 18:05 
 |  |  |  
| Boldar 
          Beiträge: 1555
 Erhaltene Danke: 70
 
 Win7 Enterprise 64bit, Win XP SP2
 Turbo Delphi
 
 | 
Verfasst: So 29.11.09 20: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: 19326
 Erhaltene Danke: 1749
 
 W11 x64 (Chrome, Edge)
 Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
 
 | 
Verfasst: So 29.11.09 21: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 22: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? |  |  |  |