AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi DLL Programmierung - Wie übergebe ich am sinnvollsten meine Daten?
Thema durchsuchen
Ansicht
Themen-Optionen

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

Offene Frage von "MyRealName"
Ein Thema von Aviator · begonnen am 30. Sep 2016 · letzter Beitrag vom 13. Okt 2016
Antwort Antwort
Seite 3 von 5     123 45      
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#21

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

  Alt 5. Okt 2016, 13:53
Hallo Fritzew,

danke für die Antwort. Das mit den Strings war mir bewusst. Nach den etlichen Tutorials die ich durchgelesen habe umso mehr.

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:


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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.137 Beiträge
 
Delphi 12 Athens
 
#22

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

  Alt 5. Okt 2016, 14:00
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.
{$MINENUMSIZE 4}
In Delphi ist das Minimum standardmäßig 1 Byte, wenn der Enum maximal 256 Werte besitzt.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#23

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

  Alt 5. Okt 2016, 14:01
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.
Fritz Westermann
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#24

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

  Alt 5. Okt 2016, 14:10
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]

Geändert von Aviator ( 5. Okt 2016 um 14:20 Uhr) Grund: Beispiel Record beigefügt
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#25

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

  Alt 5. Okt 2016, 14:51
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
Fritz Westermann
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#26

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

  Alt 5. Okt 2016, 15:23
Einfach mal so hingeschrieben aber du siehst den Flow denke ich
Also ich sehe wie du das meinst. Vielen Dank!

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.
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#27

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

  Alt 5. Okt 2016, 15:38
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
Fritz Westermann
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#28

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

  Alt 5. Okt 2016, 15:48
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.

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!
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.908 Beiträge
 
Delphi 12 Athens
 
#29

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

  Alt 6. Okt 2016, 06:35
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
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#30

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

  Alt 10. Okt 2016, 15:56
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.

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 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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 5     123 45      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:39 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