AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
Hallo Fritzew,
danke für die Antwort. Das mit den Strings war mir bewusst. Nach den etlichen Tutorials die ich durchgelesen habe umso mehr. :-D Zitat:
Wie wird denn jetzt die von dir beschriebene Funktion aufgerufen. Muss das dann auch zwingend ein Array of AnsiChar sein? Kann man da nicht einfach eine Variable vom Typ PChar nehmen? Und wenn ja, wie läuft der Aufruf dann ab sofern sich da was ändern sollte. Meine Ergebnisse können eine unterschiedliche Länge haben die ich vorher nicht kenne. Infolge dessen kann ich auch keine festen Arrays nehmen. |
AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
Delphi-Quellcode:
müssen es nicht unbedingt sein, aber man sollte dann wenigstens explizit die Speicherausrichtung definieren.
packed record
z.B.
Delphi-Quellcode:
Das Selbe gibt für ENUMs, die man vielleicht gleich auf Integer festlegen sollte, da in vielen C-Sprachen die auch immer 4 Byte sind.
type
{$ALIGN 4} // das gilt ab hier und nur bis zum Unit-Ende (oder bis zum nächsten $ALIGN in der Unit) TMyRecord = record ... end;
Delphi-Quellcode:
{$MINENUMSIZE 4}
In Delphi ist das Minimum standardmäßig 1 Byte, wenn der Enum maximal 256 Werte besitzt. |
AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
Wenn Du mit unterschiedlichen Datenlängen hantieren willst muss Sichergestellt werden wem der Speicher gehört.
Also brauchst Du dann zusätzliche Funktionen um den Speicher zu verwalten. Ähnlich wie es ja an vielen Stellen in der WINAPI gemacht wird. entweder vorher nachfragen wieviel Speicher benötigt wird oder eine Funktion um allozierten Speicher wieder freizugeben. Wobei immer die alte Regel gilt das nur der Freigibt der auch angefordert hat. |
AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
Zitat:
Wärst du so nett und würdest mir vielleicht ein Minimalbeispiel anhängen wie das dann in der Anwendung und der DLL auszusehen hat? Ich denke die Lösung mit dem Anfragen wie viel Speicher benötigt wird ist die "bessere", da sie an die WinAPI angelehnt ist. Oder siehst du das anders? [EDIT]Vergessen zu erwähnen. Ein Record müsste bei mir in etwa so aussehen (könnte auch noch erweitert werden):
Delphi-Quellcode:
[/EDIT]
TDocumentData = record
DocumentID: Int64; // Kann man den benutzen oder ist man da auf Integer beschränkt? Wäre sehr schlecht. DocumentName: PChar; // Normalerweise String (der wäre theoretisch auf 255 Zeichen begrenzt, könnte aber auch erweitert werden) DocumentDescription: PChar; // Hier steht eine Beschreibung die evtl. sogar RichText beinhalten soll Deleted: Boolean; // Der sollte ja keine Probleme machen, oder? end; |
AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
Delphi-Quellcode:
unit Unit10;
interface uses sysutils; type {$ALIGN 4} TDocumentData = record DocumentID: Int64; // Kann man den benutzen oder ist man da auf Integer beschränkt? Wäre sehr schlecht. DocumentName: PChar; // Normalerweise String (der wäre theoretisch auf 255 Zeichen begrenzt, könnte aber auch erweitert werden) DocumentDescription: PChar; // Hier steht eine Beschreibung die evtl. sogar RichText beinhalten soll Deleted: Boolean; // Der sollte ja keine Probleme machen, oder? end; function getDocumentData(const aId : Int64; var aDocument : TDocumentData): LongBool; procedure freeDocumentData(var aDocument : TDocumentData); implementation function getDocumentData(const aId : Int64; var aDocument : TDocumentData): LongBool; begin result := false; // Pick up the Data if True then begin fillchar(aDocument, sizeof(aDocument), 0); aDocument.DocumentID := aId; // reserve memory aDocument.DocumentName := Strnew('Documentname'); aDocument.DocumentDescription := StrNew('DocumentDescription'); result := true; end; end; procedure freeDocumentData(var aDocument : TDocumentData); begin if aDocument.DocumentName <> nil then StrDispose(aDocument.DocumentName); if aDocument.DocumentDescription <> nil then StrDispose(aDocument.DocumentDescription); fillchar(aDocument, sizeof(aDocument), 0); end; end. Benutzung :
Delphi-Quellcode:
procedure Test;
var data : TDocumentData; begin if getDocumentData(1, data) then begin //Use Data freeDocumentData(data); end; end; Einfach mal so hingeschrieben aber du siehst den Flow denke ich |
AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
Zitat:
Du bist jetzt aber von der anderen Variante ausgegangen, dass die Funktionen in der DLL den Speicher reservieren und auch wieder freigeben. Ist das denn der bessere Weg? :?: Wie sieht es mit meinen Anmerkungen bzgl. Int64 aus? Kann man den denn uneingeschränkt benutzen? Weil den Datentyp würde ich sehr häufig brauchen. :?: |
AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
Zitat:
Meistens ist es einfacher so. Aber ich denke das bleibt jedem selber überlassen. Sollte aber wohl am besten konsistent sein. Und Int64 benutzen wir auch viel macht keine Probleme |
AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
Zitat:
Wenn ich Fragen habe, dann melde ich mich nochmal hier. Aber jetzt habe ich auf jeden Fall schon mal einen Ansatz wie ich das lösen kann. Jetzt muss es nur noch so funktionieren wie ich mir das vorstelle. Dann wäre es perfekt. Nochmal ein dickes Danke! :thumb: :thumb: :thumb: |
AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
Könnte sein das es auch mit Messages geht:
http://docwiki.embarcadero.com/RADSt...en_mit_der_RTL Hab mal sowas läuten hören, aber nicht ausprobiert ... Rollo |
AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
Hallo zusammen,
habe jetzt schon ein gutes Stück meiner DLL fertig. Wie von Fritzew vorgeschlagen habe ich mir auch eine FreeAllocatedMemory() Procedure geschrieben die den angeforderten Speicher wieder freigibt, wenn die Informationen angekommen und zwischengespeichert sind. Funktioniert nach ein paar Tests so wie gewünscht. Ich hoffe es bleibt auch dabei. :cyclops:
Delphi-Quellcode:
Jetzt wäre die Frage, ob es hier eine einfache Möglichkeit gibt, alle PChars automatisch freizugeben?!
procedure TDMSUserManager.FreeAllocatedMemory(var UserExchange: array of TUserExchange);
var i: Integer; begin for i := Low(UserExchange) to High(UserExchange) do begin if Assigned(UserExchange[i].UserName) then StrDispose(UserExchange[i].UserName); if Assigned(UserExchange[i].FirstName) then StrDispose(UserExchange[i].FirstName); if Assigned(UserExchange[i].LastName) then StrDispose(UserExchange[i].LastName); if Assigned(UserExchange[i].EMail) then StrDispose(UserExchange[i].EMail); if Assigned(UserExchange[i].Password) then StrDispose(UserExchange[i].Password); end; end; Funktioniert da so etwas wie
Delphi-Quellcode:
? Habe es jetzt nicht ausprobiert da ich nicht weiß, ob das unter Umständen später zu Problemen führen kann. Falls ich mal meinen Record erweitern möchte (muss ja nicht dieser hier sein), dann müsste ich immer daran denken, die Strings auch wieder freizugeben. Sollte zwar in einem Zug mit dem Anfordern passieren, aber man vergisst ja gerne mal was.
Finalize()
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz