![]() |
Überarbeitung des eigenen Projektes Verbesserungen gesucht
Hallo und guten Morgen an alle,
Ich bin gerade dabei mein Projekt zu überarbeiten und vorallem Verbesserungen im Quellcode (Optimierung) durchzuführen. Erhoffe mir dadurch einen konstanteren Programmablauf. Derzeit ist gerade problematischen, dass Kommunikationen über virtuelle Comports ab und zu blockieren und somit die Maschine an der ich arbeite, selber nicht arbeiten mag :evil: . Gut nun zur Frage: Ich verwende mehrere Klassen, wobei jedes Gerät an der Maschine seine eigene Klasse hat, in der die entsprechenden DLL´s geladen werden und so weiter. Hier möchte ich Verbesserungen bewirken (vorallem die try-except-finally-Blöcke RICHTIG setzen). Das laden der DLL-Funktionen erfolgt dabei dynamisch wie folgt:
Delphi-Quellcode:
Bei der ersten Funktion habe ich schon versucht mich an die hier in der DP geposteten Konvention für try-except-finally zu halten(ist eventuell noch nicht perfekt). Bei der 2 Funktion hab ich jetzt aber noch eine Frage:
function TControlerBoard.DLLHandle_zuweisen: boolean;
begin doFehlerevent(300);// Fehlerevent teilt einer Fehlerklasse mit, dass versucht wird das DLL-Handle zu finden try ControlerDLL := TDLL_Datei.create('K8055D.DLL');// eine Dateiklasse, welche auf dem gesamten Rechner nach der angegebenen DLL sucht, in dieser Klasse wird das LoadLibary ausgeführt und mit der Variable ControlerDLL.Handle später an die TControlerBoard.DLL_Handle zugewiesen try result := ControlerDLL.Vorhanden;//ist true, wenn die DLL auf dem Rechner gefunden wurde // Handlezuweisung bei true, Fehlerhandling bei false case result of true: DLL_Handle := ControlerDLL.Handle; false: begin doFehlerevent(301); DLL_Handle := 0; end; end; except // bei Fehler Fehlerhandling und Free der DLL-Klasse doFehlerevent(302); result := false; end; finally // Beenden der Klasse ControlerDLL.Free; end; //Protokoll.Protokolleingang('ControlerBoard', 'DLLHandle-Fkt'); end; function TControlerBoard.DLLFunktionen_laden: boolean; begin //Protokoll.Protokolleingang('ControlerBoard', 'DLL-Fkt laden'); try if DLL_Handle <> 0 then begin @OpenDevice := GetProcAddress(DLL_Handle, 'OpenDevice'); @CloseDevice := GetProcAddress(DLL_Handle, 'CloseDevice'); @ClearAllAnalog := GetProcAddress(DLL_Handle, 'ClearAllAnalog'); @ClearAllDigital := GetProcAddress(DLL_Handle, 'ClearAllDigital'); @ClearAnalogChannel := GetProcAddress(DLL_Handle, 'ClearAnalogChannel'); @ClearDigitalChannel := GetProcAddress(DLL_Handle, 'ClearDigitalChannel'); @OutputAnalogChannel := GetProcAddress(DLL_Handle, 'OutputAnalogChannel'); @SetDigitalChannel := GetProcAddress(DLL_Handle, 'SetDigitalChannel'); @ReadDigitalChannel := GetProcAddress(DLL_Handle, 'ReadDigitalChannel'); @ReadAnalogChannel := GetProcAddress(DLL_Handle, 'ReadAnalogChannel'); result := true; Eingangswaechter := TControlCardControlThread.create(Form1.Handle); end else begin doFehlerevent(303); result := false; end except doFehlerevent(304); result := false; end; //Protokoll.Protokollausgang('ControlerBoard', 'DLL-Fkt laden'); end; Die try-except-Kapslung dort ist mir bewusst, dass sie falsch verwendet wird. Hatte sie damals verwendet, weil ich noch nicht so viel Ahnung hatte. Die Frage ist nun auch in Hinblick auf Assarbads Tutorial für DLL´s, ist hier die Verwendung sinnvoll? Wenn das Handle vorhanden ist, dann kenne ich ja über die Dokumentation der DLL, die Namen und bin mir eigentlich sicher, dass sie geladen werden. Das einzige Szenario, welches hier zum tragen kommen könnte, wäre ja eigentlich, dass irgendjemand irgendeiner Datei den DLL-Namen gibt. Dann würde ich, falls dann das Loadlibary noch funktioniert doch eigentlich nur einen Pointer auf Null (gemäß OH) bekommen bei den GetProcAddress-Funktionen. Also nix was wirklich zu einer Exception führen sollte (denke ich). Wenn ich also meine Funktion wie folgt abändere:
Delphi-Quellcode:
sollte diese doch in Ordnung sein oder sehe ich das jetzt total falsch oder ist eine try-except-finally-Verwendung irgendwo doch empfehlenswert?
//Protokoll.Protokolleingang('ControlerBoard', 'DLL-Fkt laden');
if DLL_Handle <> 0 then begin @OpenDevice := GetProcAddress(DLL_Handle, 'OpenDevice'); @CloseDevice := GetProcAddress(DLL_Handle, 'CloseDevice'); @ClearAllAnalog := GetProcAddress(DLL_Handle, 'ClearAllAnalog'); @ClearAllDigital := GetProcAddress(DLL_Handle, 'ClearAllDigital'); @ClearAnalogChannel := GetProcAddress(DLL_Handle, 'ClearAnalogChannel'); @ClearDigitalChannel := GetProcAddress(DLL_Handle, 'ClearDigitalChannel'); @OutputAnalogChannel := GetProcAddress(DLL_Handle, 'OutputAnalogChannel'); @SetDigitalChannel := GetProcAddress(DLL_Handle, 'SetDigitalChannel'); @ReadDigitalChannel := GetProcAddress(DLL_Handle, 'ReadDigitalChannel'); @ReadAnalogChannel := GetProcAddress(DLL_Handle, 'ReadAnalogChannel'); end; result := (@OpenDevice <>0) and (@CloseDevice <>0) and (@ClearAllAnalog <>0) and (@ClearAllDigital <>0) and (@OutputAnalogChannel <>0) and (@SetDigitalChannel <>0) and (@ReadDigitalChannel <>0) and (@ReadAnalogChannel <>0) and (@ClearAnalogChannel <>0) and (@ClearDigitalChannel <>0); if not result then doFehlerevent(303); //Protokoll.Protokollausgang('ControlerBoard', 'DLL-Fkt laden'); Vielen Dank BAMatze |
Re: Überarbeitung des eigenen Projektes Verbesserungen gesuc
Grundsätzlich ist Exception-Handling nur dort sinnvoll, wo auch Exceptions geworfen werden. Da GetProcAddress keine Exception wirft, sondern im Fehlerfall 0 zurückgibt, wäre ein try-except-Block an dieser Stelle sinnbefreit.
|
Re: Überarbeitung des eigenen Projektes Verbesserungen gesuc
Zitat:
|
Re: Überarbeitung des eigenen Projektes Verbesserungen gesuc
Wie sind denn die Variablen definiert?
Wenn z.B. OpenDevice als Prozedur/Funktion definiert wurde, dann brauchst du bei der Zuweisung kein @. Soein Sprachmischmasch wie doFehlerevent sieht auch immer nett aus ... sieht schöner aus, wenn man sich an eine Sprache hält (doErrorEvent, tueFehlerereignis, .......) <>0? Müßte es nicht <>nil sein, da es ja Zeiger sind?
Delphi-Quellcode:
result := Assigned(OpenDevice) and Assigned(CloseDevice) and ...
|
Re: Überarbeitung des eigenen Projektes Verbesserungen gesuc
@himitsu ja das mit dem nil, hab ich schon verbessert, aber trotzdem danke. Hier mal meine Deklaration für die Proceduren/ Funktionen:
Delphi-Quellcode:
Habe mich damals beim Erstellen an Fundstücken hier aus der DP orientiert.
type TOpenDevice = function(CardAddress: Longint): Longint; stdcall;
type TCloseDevice = procedure; stdcall; type TClearAllAnalog = procedure; stdcall; type TClearAllDigital = procedure; stdcall; type TClearAnalogChannel = procedure(Channel: Longint); stdcall; type TClearDigitalChannel = procedure(Channel: Longint); stdcall; type TOutputAnalogChannel = procedure(Channel, Daten: Longint); stdcall; type TSetDigitalChannel = procedure(Channel: Longint); stdcall; type TReadDigitalChannel = function(Channel: Longint): boolean;stdcall; type TReadAnalogChannel = function(Channel: Longint): Longint;stdcall; var OpenDevice: TOpenDevice; CloseDevice: TCloseDevice; ClearAllAnalog: TClearAllAnalog; ClearAllDigital: TClearAllDigital; ClearAnalogChannel: TClearAnalogChannel; ClearDigitalChannel: TClearDigitalChannel; OutputAnalogChannel: TOutputAnalogChannel; SetDigitalChannel: TSetDigitalChannel; ReadDigitalChannel: TReadDigitalChannel; ReadAnalogChannel: TReadAnalogChannel; Das mit dem Sprachmischmasch bin ich auch gerade am Ändern, Überarbeitung ist halt nötig geworden :D |
Re: Überarbeitung des eigenen Projektes Verbesserungen gesuc
Da eh keine Exceptions zu erwarten sind, mach ich es immer so:
Delphi-Quellcode:
GetProcAddress liefert bei nicht gefundener Prozedur NIL und auch bei nicht geladener DLL.
//Protokoll.Protokolleingang('ControlerBoard', 'DLL-Fkt laden');
OpenDevice := GetProcAddress(DLL_Handle, 'OpenDevice'); CloseDevice := GetProcAddress(DLL_Handle, 'CloseDevice'); ClearAllAnalog := GetProcAddress(DLL_Handle, 'ClearAllAnalog'); ClearAllDigital := GetProcAddress(DLL_Handle, 'ClearAllDigital'); ClearAnalogChannel := GetProcAddress(DLL_Handle, 'ClearAnalogChannel'); ClearDigitalChannel := GetProcAddress(DLL_Handle, 'ClearDigitalChannel'); OutputAnalogChannel := GetProcAddress(DLL_Handle, 'OutputAnalogChannel'); SetDigitalChannel := GetProcAddress(DLL_Handle, 'SetDigitalChannel'); ReadDigitalChannel := GetProcAddress(DLL_Handle, 'ReadDigitalChannel'); ReadAnalogChannel := GetProcAddress(DLL_Handle, 'ReadAnalogChannel'); result := (DLL_Handle <> 0) and Assigned(OpenDevice) and Assigned(CloseDevice) and Assigned(ClearAllAnalog) and Assigned(ClearAllDigital) and Assigned(OutputAnalogChannel) and Assigned(SetDigitalChannel) and Assigned(ReadDigitalChannel) and Assigned(ReadAnalogChannel) and Assigned(ClearAnalogChannel) and Assigned(ClearDigitalChannel); if not result then doFehlerevent(303); //Protokoll.Protokollausgang('ControlerBoard', 'DLL-Fkt laden'); PS: bei nichtgeladener DLL (DLL_Handle = 0) waren die Werte der Prozedur-Variablen nicht definiert und Result hätte da etwas falsches zurückgeben können. du hättest praktisch die Auswertung für Result mit in die IF-Abfrage reinmachen müssen.
Delphi-Quellcode:
//Protokoll.Protokolleingang('ControlerBoard', 'DLL-Fkt laden');
if DLL_Handle <> 0 then begin @OpenDevice := GetProcAddress(DLL_Handle, 'OpenDevice'); ... @ReadAnalogChannel := GetProcAddress(DLL_Handle, 'ReadAnalogChannel'); result := (@OpenDevice <>0) and (@CloseDevice <>0) and (@ClearAllAnalog <>0) and ... (@ClearDigitalChannel <>0); end else result := False; if not result then doFehlerevent(303); //Protokoll.Protokollausgang('ControlerBoard', 'DLL-Fkt laden'); |
Re: Überarbeitung des eigenen Projektes Verbesserungen gesuc
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04: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