Autor Beitrag
bruce185
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 283

winXP
D7 Ent
BeitragVerfasst: Mi 07.01.09 22:11 
Hallo,
Gibt es vieleicht eine möglichkeit record von der DLL Datei zu exportieren und in Delphi Programm dann auszulesen?

Beispiel in DLL Datei:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
library Project1;

uses
  SysUtils,
  Classes,
  IdHTTP;

type
  TTest = record
  Titel: PChar;
end;

var
  Test: TTest;

{$R *.res}

exports
  Test;


und in Delphi Programm möchte ich dann darauf zugreifen von der DLL.

z.B. so in Delphi Programm:
ausblenden Delphi-Quelltext
1:
Label1.Caption := Test.Titel;					


Ich habe dazu mal eine neue Unit angelegt:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
unit Unit2;

interface
    function addiere(zahl1, zahl2: integer): integer; stdcall;
    type
      TTest = record
      Titel: PChar;
    end;

var
  Test: TTest;

implementation

function addiere(zahl1, zahl2: integer): integer; stdcall;
external 'DLL/Project1.dll';

end.


Funktionen kann ich problemlos von der DLL Datei laden, aber wie funktioniert das mit Records?

Ich danke euch schonmal für die Hilfe.

MfG
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 07.01.09 22:53 
Variablen kann man nicht exportieren. Da musst du schon eine entsprechende Funktion / Prozedur schreiben zum Auslesen.

Wenn es um die Deklaration des Records geht: Diese kannst du ja in eine gemeinsam genutzte Unit schreiben.
dummzeuch
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 593
Erhaltene Danke: 5


Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
BeitragVerfasst: Do 08.01.09 22:33 
user profile iconbruce185 hat folgendes geschrieben Zum zitierten Posting springen:

Gibt es vieleicht eine möglichkeit record von der DLL Datei zu exportieren und in Delphi Programm dann auszulesen?


Delphi erlaubt das nicht (wohl aber C). Aber es gibt die Moeglichkeit, die Adresse eines Records als Funktionsergebnis zurueckzuliefern und auf dieses dann mittels Pointer-Referenz zuzugreifen:

DLL:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
type
  TMyRecord = record
    Feld1: integer;
    Feld2: double;
  end;
  PMyRecord = ^TMyRecord;

var
  gblMyRecord: TMyRecord;

function GetMyRecAddr: PMyRecord; export;
begin
  Result := @gblMyRecord;
end;


Programm:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
type
  TMyRecord = record
    Feld1: integer;
    Feld2: double;
  end;
  PMyRecord = ^TMyRecord;

var
  MyRec: PMyRecord;

begin
  MyRec := GetMyRecAddr;
  MyRec^.Feld1 := 0;
end;


Aber das geht nur unter folgenden Voraussetzungen:

1. Die Record-Deklaration muss in Programm und DLL exact uebereinstimmen, incl. des Alignments. Ich wuerde vorsichtshalber als erstes Feld die Laenge des Records als Integer abspeichern, dieses Feld in der DLL mit Sizeof(gblMyRecord) initialisieren und im Programm auf Sizeof(TMyRecord) ueberpruefen, dann schliesst Du schonmal die groebsten Schnitzer aus.
2. Das Record darf keine dynamischen Felder (Strings, dyn. Arrays, Objekte, Interfaces) enthalten. Sicher sind Integer, single, double und extended, boolean, enums (gleiche Deklaration vorausgesetzt).
3. Das Record muss in der DLL entweder wie oben als globale Variable deklariert sein, oder aber auf dem Heap alloziert werden. In letzterem Fall muss Du darauf achten, dass es in der DLL nicht freigegeben wird, solange es im Programm verwendet wird.

Und selbst wenn Du all das beachtest, wirst Du vermutlich weitere Probleme damit haben, auf die ich im Moment gerade nicht komme. ;-)

In der Regel macht man es aber umgekehrt: Das Programm alloziert einen Record und uebergibt ihn per Prozeduraufruf an die DLL, welche ihn dann zur Kommunikation mit dem Programm verwendet. Das Programm ist dann auch fuer die Freigabe des Speichers zustaendig. Auch hier gelten o.g. Einschraenkungen.

twm
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 08.01.09 23:30 
user profile icondummzeuch hat folgendes geschrieben Zum zitierten Posting springen:
In der Regel macht man es aber umgekehrt: Das Programm alloziert einen Record und uebergibt ihn per Prozeduraufruf an die DLL, welche ihn dann zur Kommunikation mit dem Programm verwendet. Das Programm ist dann auch fuer die Freigabe des Speichers zustaendig. Auch hier gelten o.g. Einschraenkungen.

Genauer: Im Programm reserviert man Speicher für den Record dessen Adresse man dann an die DLL übergibt. Die DLL füllt dann den Speicher mit den passendenden Werten. So wird es auch bei API-Funktionen von Windows gemacht.
christoph79
Hält's aus hier
Beiträge: 1



BeitragVerfasst: Do 19.03.09 10:23 
Hallo,

ich glaube/hoffe, das passt hier auch wirklich dazu:

Ich hab mir gerade Apache-Module in delphi angeschaut und für mich sieht das so aus, als ob da ein record exportiert wird.

in der dpr:
ausblenden Delphi-Quelltext
1:
2:
exports
  apache_module name 'meinmodul_module';


in der ApacheTwoApp.pas
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
interface
(...)
var
(...)
  apache_module: module; 
  {$EXTERNALSYM apache_module}


und schließlich in der HTTPD2.pas
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  module = {$IFDEF LINUX}packed{$ENDIF} record
  (...)
  end;
  {$EXTERNALSYM module}


Wenn ich schief gewickelt sein sollte, freue ich mich natürlich über Richtigstellung ;-)

Grüße,
Chris