![]() |
Zugriffsverletzung bei DLL-Benutzung
Hallo Leute!
Ich habe heute zum ersten mal das Programmieren mit DLLs ausprobiert und musste leider feststellen, dass es zu einer Zugriffsverletzung beim Schließen des Programms mit der DLL kommt. Es werden KEINE STRINGS übergeben, da ich bereits gelesen habe, dass das zu Problemen führen kann! Ich habe außerdem noch den Ratschlag von Delphi befolgt "Sharemem" zu den Uses der Unit UND des Projekts hinzuzufügen! Die DLL liegt auch im Stammverzeichnis des Projekts! Hier ist der Ausschnitt aus der DLL, den ich verwende:
Delphi-Quellcode:
So deklariere ich die Prozedur aus der DLL in meinem Hauptprogramm:
library Bianfable;
uses SysUtils, Classes, Windows, Messages, Graphics, Controls, Forms, Dialogs, StdCtrls, IniFiles, JPEG, ShellAPI, Menus; procedure CenterWindow(F: TForm); stdcall; begin F.Left := Screen.Width div 2 - F.Width div 2; F.Top := Screen.Height div 2 - F.Height div 2; end; //... exports CenterWindow, //...; begin end.
Delphi-Quellcode:
Und so benutze ich die Prozedur schließlich:
type
//... procedure CenterWindow(F: TForm); stdcall; external 'Bianfable.dll'; var //...
Delphi-Quellcode:
Wär echt nett, wenn ihr mir sagen könntet, was ich noch falsch mache...
procedure TForm1.FormCreate(Sender: TObject);
begin CenterWindow(Form1); end; Bianfable... |
Re: Zugriffsverletzung bei DLL-Benutzung
Du kannst keine VCL-Objekte zwischen DLL und Applikation austauschen. Dazu bräuchtest Du eine *.bpl
|
Re: Zugriffsverletzung bei DLL-Benutzung
Ist eine Form den eine VCL-Komponente???
Außerdem gibts die Fehlermeldung ja beim beenden des Programms, die eigentliche Verwendung des Quelltextes ist da eigentlich schon abgeschlossen (erfolgreich)! |
Re: Zugriffsverletzung bei DLL-Benutzung
Ja, eine Form ist auch eine VCL-Komponente. Du könntest aber z.B. das Handle der Form an die DLL übergeben und in der DLL damit arbeiten, das sollte keine Probleme geben.
|
Re: Zugriffsverletzung bei DLL-Benutzung
Es geht nicht nur um VCL-Komponenten sondern generell um Objecte. Das der Fehler erst beim Beenden kommt hast du richtig erkannt. Problem ist das die DLL und deine Anwendung getrennte Speichermanager verwenden. Beim Beenden versuchen diese den Speicher frei zugeben und da kommt es zu Fehlern weil der eine Speichermanager versucht Dinge frei zu geben die er gar nicht angefordert hat.
Aber man sollte generell keine Objecte zwischen DLL und Anwendung austauschen. Dafür gibt es BPLs. Diese haben den Vorteil das sicher gestellt wird das die Objecte in der DLL(BPL) identisch mit denen außerhalb der DLL(BPL) sind. Denn bei normaler Verwendung per DLL stellt ja niemand sicher das ein Object aus der DLL von der gleichen Delphiversion mit dem gleichen Speicheraufbau stammt. |
Re: Zugriffsverletzung bei DLL-Benutzung
Ok...vielen Dank!!!
|
Re: Zugriffsverletzung bei DLL-Benutzung
Zitat:
|
Re: Zugriffsverletzung bei DLL-Benutzung
Ich verstehe nicht warum, immer alle sagen, zwischen DLL und Host könnten keine Objekte ausgetauscht werden. In meiner 2D Bibliothek mache ich das ständig und das funktioniert einwandfrei. Wer es nicht glauben kann schaut hier nach:
DLL-Hauptunit: ![]() DLL-Klassenimplementierungen: ![]() Die einzige Einschränkung, die mir bis jetzt aufgefallen ist, ist die Tatsache, dass man nicht auf die RTTI Informationen der im Plugin erzeugten Objekte zugreifen kann und das man in der DLL keine größeren Speicherbereiche reservieren kann, auf die dann die Hostapplikation zugreifen darf. In die andere Richtung geht jedoch auch das einwandfrei. Ich schätze das die BPLs zum großen Teil nur das Problem mit den RTTI Informationen beheben. Daher vermute ich, dass das hier geschilderte Problem von den in der DLL verwendeten Units kommt, die beim Entladen der Bibliothek versuchen Finalisierungsarbeiten auszuführen, die dann (also in der Bibliothek) jedoch nicht funktionieren. |
Re: Zugriffsverletzung bei DLL-Benutzung
Ich sehe beim modulübergreifenden Arbeiten mit DLLs zwei Probleme.
1. Wenn Objekte Strings oder andere Sprachkonstrukte verwenden, die den Speichermanager nutzen. Besonders fies ist das bei Bibliotheken wie der VCL. 2. Wenn explizit oder implizit auf die RTTI zugegriffen wird. Ich habe hier mal einen Ersatz für den as-Operator gepostet, der das Problem umgeht. Mit externen Bibliotheken funktioniert er natürlich nicht. Interessanterweise verwendet Delphi selbst einen modifizierten is-Operator beim Exception-Handling mit der on-EWuppdi-do-Syntax, sodass es möglich sein sollte, modulübergreifend Exceptions zu fangen. Worin ich ehrlich gesagt kein Problem sehe, ist das Allozieren und Freigeben von Objekten. Glücklicherweise sind nämlich TObject.Destroy und TObject.FreeInstance virtuell, sodass der richtige Speichermanager das Objekt freigibt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:46 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