![]() |
Re: DLL dynamisch laden
Zitat:
|
Re: DLL dynamisch laden
Muss es nicht "VerbindenVT := " anstatt "@VerbindenVT := " heißen?
|
Re: DLL dynamisch laden
Zitat:
Danke @ all |
Re: DLL dynamisch laden
Hallo nochmal an alle,
muss diesen Thread nochmal aufnehmen, da sich neue Probleme auftun. Ich habe mit den Hinweisen, die hier schon gegeben wurden die Funktionen ausgelesen, die mir die mitgelieferte DLL gibt. Diese habe ich nach dem im Eingangsthreat vorliegenen Muster (Delphi-Code) eingebunden. Jetzt hab ich aber festgestellt, dass er selbst auf dem Comport für das Gerät mit den Proceduren aus der DLL, so wie ich sie eingebunden hab nicht anspringt. Hab aber auch nach längerem Suchen keinen Fehler gefunden. Fällt jemanden vieleicht etwas auf, was ich übersehen hab. vielen Dank BAMatze |
Re: DLL dynamisch laden
Ist schwer von hier aus dahinterzusteigen, da die wenigsten deine benutzte API/DLL kennen.
Hast du die Rückgabewerte geprüft? |
Re: DLL dynamisch laden
@sirius
Habe das erstmal wie folgt gelöst. Weiß nicht, ob das so wirklich logisch ist aber bisher tut es seine Tätigkeit. Hier erstmal der Code: in der ersten Unit wird geprüft, ob die DLL vorhanden ist. Wenn sie vorhanden ist, wird eine Komponente kreiert, die in der 2. Unit eingeführt wird.
Delphi-Quellcode:
In der 2. Unit wird die TV_Tische-Class eingeführt und hier sämtliche benötigten Funktionen statisch aus der DLL ausgelesen. Das war leider so nötig, wegen den Problemen, die beim dynamischen Laden aufgetreten sind.
function THUnterthread.DLL_suche(const sDatei: string): THandle;
var DLL_Handle: THandle; begin try DLL_Handle:=LoadLibrary(PChar(ExtractFilePath(ParamStr(0))+sDatei)); if DLL_Handle <> 0 then result := DLL_Handle else result := 0 except result := 0; end; end; procedure THUnterthread.Verschiebetische_initialisieren; begin iThreadmsg := 2; if DLL_suche('MMC.DLL') <> 0 then begin V_Tische := TV_Tische.create; iThreadmsg := 3; VTComPort_ermitteln; Komponente_anlegen('MMC.DLL','Verschiebetische', VTComPort_ermitteln); end else iThreadmsg := 4; end;
Delphi-Quellcode:
Im Nachhinein ist es glaube ich auch möglich dies alles dynamisch zu machen. Werde dies auch gleich mal probieren. Das Problem an sich ist, dass ich wenn ich für die meisten boolschen-DLL-Funktionen die mir die DLL bietet auf einer Com-Schnittstelle, an der ein anderes Gerät angeschlossen ist (bei mir war das z.B. die Maus) meist den Wert true zurück bekam. Dadurch wurde die Verifizierung des richtigen Com-Ports sehr schwierig. Deswegen habe ich die MST_moving benutzt, da dies die einzige von mir gefundene DLL-Funktion ist, die wirklich true ist, wenn die Tische angesprochen werden.
unit VT_Funktionen;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, ComCtrls; const maxComPort = 100; Bautrate = 9600; ExtLib = 'MMC.DLL'; constMillimeter = 6400; type TV_Tische = class private Tischbmp: TBitmap; function Bewegtsich(const Kanal: integer): boolean; function Bremsen: boolean; function Geschwindigkeit_festlegen(const iGeschwindigkeit: integer): boolean; function Beschleunigung_festlegen(const iBeschleunigung: integer): boolean; public DLL_Handle: THandle; bBewegung, bkalibriert: boolean; iaktuelleTischposition, iZielTischposition, iComport, iFehlercode: integer; bAngeschlossen: boolean; constructor create; reintroduce; destructor Destroy; override; function VTische_verbinden(Comport: integer): boolean; function Kalibrierung(const Kanal: integer): boolean; function BewegenABS(dneuPos: double): boolean; overload; function BewegenABS(const KaliPos: string): boolean; overload; function BewegenABS(dneuPos: double; iGeschwindigkeit: integer): boolean; overload; function BewegenABS(dneuPos: double; iGeschwindigkeit, iBeschleunigung: integer):boolean; overload; end; {*********************************************************************************** * allgemeine Funktionen für Verschiebetische * ***********************************************************************************} {**********************************Ende Funktionen**********************************} {*********************************************************************************** * Funktionen für Verschiebetische * ***********************************************************************************} function MMC_COM_open(portnumber,baudrate:integer):integer; stdcall external ExtLib; function MMC_COM_close:integer; stdcall external ExtLib; // function MMC_COM_setBuffer:integer; stdcall external ExtLib; // function MMC_sendString(pCmd:pChar):integer; stdcall external ExtLib; // function MMC_sendCommand(pCmd:pChar):integer; stdcall external ExtLib; // function MMC_getPos:integer; stdcall external ExtLib; // function MDC_getPosErr:integer; stdcall external ExtLib; // function MMC_getVal(query:integer):integer; stdcall external ExtLib; // function MMC_getReport(pCmd,psRead:PChar):integer; stdcall external ExtLib; // function MMC_getStringCR(psRead:PChar):integer; stdcall external ExtLib; // function MDC_moving:integer; stdcall external ExtLib; // function MST_moving:integer; stdcall external ExtLib; // function MMC_initNetwork(maxaxis:integer):integer; stdcall external ExtLib; // function MMC_select(newaxis:integer):integer; stdcall external ExtLib; // function MMC_setDevice(newaxis:integer):integer; stdcall external ExtLib; // function MMC_COM_clear:integer; stdcall external ExtLib; // function MMC_COM_EOF:integer; stdcall external ExtLib; // function MMC_getSTB(byteno:integer):integer; stdcall external ExtLib; // function MDC_waitStop:integer; stdcall external ExtLib; // function MST_waitStop:integer; stdcall external ExtLib; // function MMC_getDLLversion:integer; stdcall external ExtLib; function MMC_moveA(axis,position:integer):integer; stdcall external ExtLib; function MMC_moveR(axis,shift:integer):integer; stdcall external ExtLib; function MMC_getMacro(macno:integer;content:PChar):integer; stdcall external ExtLib; function MMC_globalBreak:integer; stdcall external ExtLib; {**********************************Ende Funktionen**********************************} implementation constructor TV_Tische.create; begin inherited create; bBewegung := false; bkalibriert := false; bAngeschlossen := false; end; function TV_Tische.Geschwindigkeit_festlegen(const iGeschwindigkeit: Integer): boolean; begin try MMC_sendCommand(PAnsiChar('SV'+inttostr(iGeschwindigkeit))); result := true; except result := false; end; end; function TV_Tische.Beschleunigung_festlegen(const iBeschleunigung: Integer): boolean; begin try MMC_sendCommand(PAnsiChar('SA'+inttostr(iBeschleunigung))); result := true; except result := false; end; end; function TV_Tische.Bremsen: boolean; begin try Geschwindigkeit_festlegen(0); Beschleunigung_festlegen(0); MMC_sendCommand('AB') except end; end; function TV_Tische.BewegenABS(dneuPos: double): boolean; begin Geschwindigkeit_festlegen(500); Beschleunigung_festlegen(500); MMC_sendCommand(PAnsiChar('MA' + inttostr(round(dneuPos*constMillimeter)))); end; function TV_Tische.BewegenABS(const KaliPos: string): boolean; begin Geschwindigkeit_festlegen(1000); Beschleunigung_festlegen(1000); MMC_sendCommand(PAnsiChar(KaliPos)); end; function TV_Tische.BewegenABS(dneuPos: double; iGeschwindigkeit: integer): boolean; begin Geschwindigkeit_festlegen(iGeschwindigkeit); Beschleunigung_festlegen(500); MMC_sendCommand(PAnsiChar('MA' + inttostr(round(dneuPos*constMillimeter)))); end; function TV_Tische.BewegenABS(dneuPos: Double; iGeschwindigkeit: Integer; iBeschleunigung: Integer): boolean; begin Geschwindigkeit_festlegen(iGeschwindigkeit); Beschleunigung_festlegen(iBeschleunigung); MMC_sendCommand(PAnsiChar('MA' + inttostr(round(dneuPos*constMillimeter)))); end; function TV_Tische.VTische_verbinden(Comport: integer): boolean; begin try MMC_COM_open(Comport, Bautrate); BewegenABS('FE2'); if MST_moving = 1 then begin Bremsen; end except result := false; end; end; function TV_Tische.Kalibrierung(const Kanal: integer): boolean; begin try MMC_setDevice(Kanal); BewegenABS('FE2'); except end; end; function TV_Tische.Bewegtsich(const Kanal: integer): boolean; begin MMC_setDevice(Kanal); if MST_moving = 1 then result := true else result := false; end; destructor TV_Tische.Destroy; begin Bremsen; MMC_COM_close; inherited Destroy; end; end. Wie gesagt, mit den Erkenntnissen sollte es jetzt auch möglich sein, alles dynamisch zu machen. Meine neue Frage hierzu wäre: Ist dies wirklich noch nötig oder kann ich es so lassen? Vielen Dank BAMatze |
Re: DLL dynamisch laden
Ich denke in deinem Fall ist statisches Einbinden der DLL besser geeignet. Durch dynamisches Einbinden kann man halt nur sicherstellen, dass das Programm auch läuft, wenn die DLL nicht vorhanden ist. Man kann das Fehlen der DLL quasi abfangen. Wichtig dazu ist, wie gesagt, dass das Programm auch ohne diese DLL funktionieren würde. Das ist aber bei dir nicht der Fall. Deswegen -> statisch einbinden. Wenn die DLL tatsächlich nicht existiert schmeißt Windows bereits beim Laden deines Programms eine Fehlermeldung raus und der User kann sich kümmern. Etwas anderes kannst du ja auch nicht machen.
Wenn du allerdings die DLL statisch einbindest, brauchst du im Programm nicht mehr zu testen, ob sie wirklich da ist (mit allen Funktionen die du benötigst). Das hat, wie gesagt, Windows schon für dich gemacht. Windows macht das übrigens nicht so aus Jux und Dallerei, sondern es muss ja die Importtabelle deiner EXE für alle statisch eingebundenen Funktionen füllen. |
Re: DLL dynamisch laden
@sirius
Du hast Recht. Also werde ich dies nochmal ändern müssen. Möchte, dass das Programm auch startet, wenn die DLL nicht vorhanden ist. Mich verwirrt jetzt eigentlich nur, dass in der Entwicklungsumgebung dies nicht passiert. Hier hatte ich das eigentlich schon so abgefangen, dass er mir gesagt hat im Programm, ob die Datei vorhanden ist oder nicht. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:52 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