![]() |
TObject, DLL, DLL Freigabe
Hallo Alle... 8-)
Der Titel ist nur eine Stichwortsammlung. :roll: 1. Gegeben: Datenobjekte (unwichtiges entfernt)
Delphi-Quellcode:
2.Gegeben:
TMasterDeviceVersion = class
strict private var FModel: string; FAppVersion: string; FSysVersion: string; public property Model: string read FModel write FModel; property AppVersion: string read FAppVersion write FAppVersion; property SysVersion: string read FSysVersion write FSysVersion; end; TMasterDevice = class strict private FVersion: TMasterDeviceVersion; public constructor Create; destructor Destroy; override; property Version: TMasterDeviceVersion read FVersion write FVersion; ... end; . . constructor TMasterDevice.Create; begin FVersion:= TMasterDeviceVersion.Create; end; destructor TMasterDevice.Destroy; begin FVersion.Free; inherited; end; Auszug aus DLL
Delphi-Quellcode:
Problem:
procedure ParseVersion(const aText: PChar; MasterVersion: TMasterDeviceVersion); stdcall;
var sl: TStringList; I, J: Integer; begin sl:= TStringList.Create; try sl.Text:= aText; for I:= 0 to sl.Count - 1 do begin if AnsiStartsText('var verAp', sl[I]) then begin for J:= 12 to Length(sl[I]) do begin if sl[I][J] = ' ' then begin MasterVersion.Model:= Copy(sl[I], 12, J - 12); MasterVersion.AppVersion:= Copy(sl[I], J + 1, Length(sl[I]) - J - 2); Break; end; end; end; if AnsiStartsText('var verSist', sl[I]) then begin MasterVersion.SysVersion:= Copy(sl[I], 14, Length(sl[I]) - 15); end; end; finally sl.Free; end; end; 1. Die Instanz von TMasterDevice wird im Hauptthread erzeugt 2. Die DLL wird dynamisch geladen 3. Der DLL Procedure wird der "Text" und die MasterVersion übergeben. 4. Wenn die Procedure Parse Version zurückkommt sind alle Versions Properties korrekt gefüllt. 5. Wenn ich nun die DLL freigebe steht in MasterVersion nur Müll drin. Im Master Objekt, welches auch über die DLL gefüllt wird ist alles noch korrekt. Kann mir einer die Ursache erklären? Nachtrag: Aufruf der Procedure aus der DLL
Delphi-Quellcode:
if LoadMessage.Data > '' then
begin FParseVersion(PChar(LoadMessage.Data), FMasterDevice.Version); if FMasterDevice.Version.AppVersion > '' then // hier ist korrekt gefüllt... Basis DLL geladen begin LoadMasterDeviceDLL; // gibt ein vorhandenes DLL Handle (Basis DLL) frei und lädt die passende DLL nach Version end; if Assigned(FOnVersion) then // hier steht dann Müll im FMasterDeviceVersion direkt nach der Freigabe in LoadMasterDeviceDLL FOnVersion(self, True); end |
AW: TObject, DLL, DLL Freigabe
Wenn Du Delphi Objekte im Interface zwischen Hauptprogramm und Bibliothek verwenden willst darfst Du keine Dlls sondern musst Bpls verwenden. Oder du musst ein "flache" Schnittstelle verwenden.
|
AW: TObject, DLL, DLL Freigabe
Danke für deine Antwort.
Solange ich die DLL nur mit dem Delphi Programm benutze soll es keine Probleme geben. Es funktioniert ja auch, solange die DLL geladen bleibt. Da aber das Objekt im Hauptthread erzeugt wird verstehe ich nicht wieso die Freigabe der DLL den Inhalt beeinflußt. :gruebel: |
AW: TObject, DLL, DLL Freigabe
Ich versuchs mal mit meinen bescheidenen Wissensstand:
Es sind zwei verschiedene Speichermanager! Einer in der Anwendung, einer in der DLL. Die Strings (AppVersion, Model...) unterliegen den Speichermanager der DLL. Wenn die DLL entladen wird, werden auch alle referenzgezählten Typen darin freigeben, also die Strings! Ergebnis: Du hast im MasterVersion-Objekt in deiner Anwendung zwar noch gültige Adressen auf irgendwelche Speicherbereiche, aber da steht jetzt was anderes bzw. Müll drin. |
AW: TObject, DLL, DLL Freigabe
Danke erstmal 8-)
Zitat:
|
AW: TObject, DLL, DLL Freigabe
Zitat:
@mkinzler: Was ist eine "flache Schnittstelle"? |
AW: TObject, DLL, DLL Freigabe
Zitat:
Zitat:
|
AW: TObject, DLL, DLL Freigabe
@mkinzler
Kannst du mal skizzieren wie ich eine DLL über ein Interface anbinde und keine "Speicher" Probleme habe. Wenn ich mir von der DLL das Interface auf die "Proceduren" geben lasse ist das Speicherproblem Geschichte? |
AW: TObject, DLL, DLL Freigabe
Im Grunde sehr einfach:
Delphi-Quellcode:
Und dann:
IMasterDeviceVersion = interface
['{DF6962EE-B638-4B59-9BE6-82B8BB369477}'] function GetAppVersion: WideString; function GetModel: WideString; function GetSysVersion: WideString; procedure SetAppVersion(const Value: WideString); procedure SetModel(const Value: WideString); procedure SetSysVersion(const Value: WideString); property Model: WideString read GetModel write SetModel; property AppVersion: WideString read GetAppVersion write SetAppVersion; property SysVersion: WideString read GetSysVersion write SetSysVersion; end; TMasterDeviceVersion = class(TInterfacedObject, IMasterDeviceVersion) strict private var FModel: WideString; FAppVersion: WideString; FSysVersion: WideString; function GetAppVersion: WideString; function GetModel: WideString; function GetSysVersion: WideString; procedure SetAppVersion(const Value: WideString); procedure SetModel(const Value: WideString); procedure SetSysVersion(const Value: WideString); public property Model: WideString read GetModel write SetModel; property AppVersion: WideString read GetAppVersion write SetAppVersion; property SysVersion: WideString read GetSysVersion write SetSysVersion; end;
Delphi-Quellcode:
Du darfst dann natürlich auch in der Anwendung nur noch mit IMasterDeviceVersion usw. arbeiten.
procedure ParseVersion(const aText: PChar; MasterVersion: IMasterDeviceVersion); stdcall;
// |
AW: TObject, DLL, DLL Freigabe
Danke, das ist wirklich zu einfach. Warum nicht gleich so? :oops:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:26 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