Delphi-PRAXiS
Seite 3 von 5     123 45      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten? (https://www.delphipraxis.net/190411-dll-programmierung-wie-uebergebe-ich-am-sinnvollsten-meine-daten.html)

Aviator 5. Okt 2016 13:53

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:

Zitat von Fritzew (Beitrag 1349845)
Delphi-Quellcode:
const
 cwmaxnamesize = 30;
type
 tApi_Materialrec = packed record
    Name: array [0 .. cwmaxnamesize - 1] of Ansichar;
    Group: array [0 .. cwmaxnamesize - 1] of Ansichar;
    MatCode: array [0 .. cwmaxnamesize - 1] of Ansichar;
    Mate1, mate2, mate3, matg1, matg2, matgew: single; // Materialgewicht

    Mattyp: integer;
    list_matbez,
    mat_photoflag,
    mat_photo1,
    mat_photo2: integer;
  end;
Funktionen geben niemals Records zurück sondern sind bei uns immer aufgebaut nach dem Schema:


Delphi-Quellcode:
function getMatDataforId(aid : Integer; var matrec : tApi_Materialrec) : Bool;
Das funktioniert bei uns soweit problemlos.

Die Funktion hätte ich auch mit einem Var Parameter aufgebaut, da ich das so auch aus der WinAPI kenne.

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.

himitsu 5. Okt 2016 14:00

AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
 
Delphi-Quellcode:
packed record
müssen es nicht unbedingt sein, aber man sollte dann wenigstens explizit die Speicherausrichtung definieren.
z.B.
Delphi-Quellcode:
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;
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.
Delphi-Quellcode:
{$MINENUMSIZE 4}

In Delphi ist das Minimum standardmäßig 1 Byte, wenn der Enum maximal 256 Werte besitzt.

Fritzew 5. Okt 2016 14:01

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.

Aviator 5. Okt 2016 14:10

AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
 
Zitat:

Zitat von Fritzew (Beitrag 1349853)
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.

Okay. Habe zwar bisher wenig mit der WinAPI gearbeitet, aber das Prinzip habe ich verstanden. Allerdings hänge ich bei der Umsetzung noch ein wenig.

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:
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;
[/EDIT]

Fritzew 5. Okt 2016 14:51

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

Aviator 5. Okt 2016 15:23

AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
 
Zitat:

Zitat von Fritzew (Beitrag 1349866)
Einfach mal so hingeschrieben aber du siehst den Flow denke ich

Also ich sehe wie du das meinst. Vielen Dank! :thumb:

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. :?:

Fritzew 5. Okt 2016 15:38

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. :?:
Wir benutzen meistens diesen Weg einfach weil es für uns der bessere Flow ist.
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

Aviator 5. Okt 2016 15:48

AW: DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
 
Zitat:

Zitat von Fritzew (Beitrag 1349874)
Wir benutzen meistens diesen Weg einfach weil es für uns der bessere Flow ist.
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

Super danke dir! Ich werde das jetzt mal so ausprobieren. :coder2: :coder:

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:

Rollo62 6. Okt 2016 06:35

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

Aviator 10. Okt 2016 15:56

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:
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;
Jetzt wäre die Frage, ob es hier eine einfache Möglichkeit gibt, alle PChars automatisch freizugeben?!

Funktioniert da so etwas wie
Delphi-Quellcode:
Finalize()
? 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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:41 Uhr.
Seite 3 von 5     123 45      

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