DLL-Programmierung
Was sind DLLs?
DLL ist die Abkürzung für „Dynamic Link Library“. DLLs sind Bibliotheken mit offener Schnittstelle, d.h. man kann Funktionen/Proceduren in anderen Programmen verwenden. Dabei muss die DLL aber nicht in der gleichen Sprache geschrieben sein, die DLL kann z.B. in C geschrieben sein und das Hauptprogramm in Delphi. DLLs sind sinnvoll, wenn man eine Funktion häufig nutzt oder Routinen zur Verfügung stellen will ohne gleich den Quelltext offen legen zu müssen.
Schreibweise
Was man unter anderem bei der DLL-Programmierung beachten muss, ist die Schreibweise von Procedure und Variabelennamen. „Testanwendung“ ist nicht das Gleiche wie „TestAnwendung“. Es wird, wie in vielen anderen Sprachen auch, die Groß/Kleinschreibung unterschieden. Pascal/Delphi unterscheidet dieses bei der normalen Programmierung sonst nicht, von der DLL-Programmierung mal abgesehen.
DLL-Programmierung – Ganz einfach
Die Programmierung einer DLL unter Delphi ist relativ einfach. Dazu musst Du nur „Datei|Neu“ und dann „DLL“ wählen.Der Rohbau einer Pascal-DLL:
library //DLLName; uses //Eingebundene Units procedure //Procedurename; //Aufrufkonvention; begin //Procedure end; exports //Procedurename //evtl. resident, //Procedurename //evtl. resident; begin //Initialisierungsroutine optional end;
Eine DLL ist ähnlich aufgebaut wie eine Unit:
- Statt „Unit“ beginnt der Quelltext mit „library“
- Der „uses“-Abschnitt, in welcher die eingebundenen Units aufgeführt werden ist auch vorhanden.
- Es fehlt das kleine Wort „implementation“
- Proceduren und Funhktionen können wie gewohnt „hingeschrieben“ werden.
- Zusätzlich muss hinter der Procedure/Funktion die Art des Aufrufes festgelegt werden, die sog. Aufrufkonvention. Zu empfehlen ist die Aufrufkonvention „stdcall“.* Zum Schluss müssen die exportierten Proceduren und Funktionen aufgeführt werden, damit man diese in anderen Programmen auch benutzen kann. Sie werden mit einem Komma voneinander getrennt. Die Anweisung „resistent“ bedeutet, dass eine DLL auch nach dem Beenden eines Programms im Speicher gehalten werden soll. Daraus resultiert eine kürzere Ladezeit.
Beachte, dass man in DLLs keine Strings exportieren oder importieren sollte. Die Delphi Strings sind nicht 100% kompatibel zu den Strings aus C oder C++. Benutze deshalb immer PChars anstatt Strings für den Im- und Export.
Konvertierung PChar => String:
Edit1.Text:=string(PCharVariable);
Konvertierung String => PChar:
PCharProcedure(PChar(Edit1.Text)); PCharProcedure('Dies ist auch ein PChar');
Einbindung von DLLs
Es gibt zwei Möglichkeiten DLLs, bzw. dessen exportierten Funktionen/Proceduren einzubinden:
- statische Einbindung
- dynamische Einbindung
Meistens genügt es die DLL statisch einzubinden. Diese Methode ist außerdem sicherer. Beim Compilieren wird eine direkter Hinweis auf die DLL in die EXE gelinkt. Beim Programmaufruf wird das Programm erst geladen, nachdem die DLL im Speicher ist. Die dynamische Einbindung benutzt man meistens bei Plug-Ins oder wenn man nur einmal während des Programmablaufs eine Funktion aus der DLL benötigt.Die statische Einbindung einer DLL-Routine ist relativ simpel:
procedure Test(s: PChar); stdcall; external 'dllname.dll';
„stdcall“ ist dabei die Aufrufkonvention. Sie muss die Gleiche sein, wie in der DLL. Hinter dem Schlüsselwort „external“ befindet sich der Name der DLL. Jetzt kann die Procedurem wie gewohnt im Hauptprogramm verwendet werden.
Fehlerbehandlung
(Erwartete) Fehler kann man wie bei normalen Programmen in einem Try-except-Block kapseln. Um Speicher zu schützen sollte der try-finally-Block verwendet werden. Wenn auf eine solche Fehlerbehandlung verzichtet und es tritt trotzdem ein Fehler auf, wird dieser an das Programm weitergegeben. Delphi ist in diesem Zusammenhang sehr tolerant, fast kein Fehler führt zum Programmabbruch. Ganz anders sieht die Sache bei Visual Basic aus.
Export von Formularen
Wenn man häufig die gleichen Formulare benötigt, ist eine DLL mit eingebundenen Formularen ideal. Die Vorgehensweise gleicht dem Erstellen „normaler“ Projekte: Man wirft die Komponenten aufs Formular und erstellt die Ereignisroutinen. Um das Projekt in eine DLL zu verwandeln geht man dann folgendermaßen vor:
- In der Projektdatei das Hauptprogramm löschen (Application.CreateForm(TForm1, Form1);)
- Ändern des Bezeichner „programm“ in „library“
- Erstellen einer Schnittstellenroutine
- In der Schnittstellenroutine wird das Formular „createt“ und angezeigt
Der Quellcode dazu würde so aussehen:
procedure DLLFormular; var Form1: TForm1; begin Form1 := TForm1.Create(Application); try Form1.ShowModal; finally Form1.Release; end; end;