Autor Beitrag
GuaAck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 378
Erhaltene Danke: 32

Windows 8.1
Delphi 10.4 Comm. Edition
BeitragVerfasst: Mo 03.02.14 23:15 
Liebe Experten,

ich möchte im Delphi eine in Standard-C defnierte DLL nutzen. So etwas habe ich schon gemacht, aber bei der Syntax der folgenden Header-Datei in C komme ich mit meinem Basiswissen in C nicht weiter:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
// C-Code
// ========
// typedef enum  {fmiOK, fmiWarning, fmiDiscard, fmiError, fmiFatal} fmiStatus;
// typedef void  ( *fmiCallbackLogger)        (fmiComponent c, fmiString instanceName, fmiStatus status,
//                                             fmiString category, fmiString message, ...);
// typedef void* ( *fmiCallbackAllocateMemory)(size_t nobj, const size_t size);
// typedef void  ( *fmiCallbackFreeMemory)    (void* obj);
//
// typedef struct {
//     fmiCallbackLogger         logger;
//     fmiCallbackAllocateMemory allocateMemory;
//     fmiCallbackFreeMemory     freeMemory;
//   } miCallbackFunctions;

// Übersetzung Delphi; hier nicht angeführte Typen sind elementare Delphi-Typen wie Integer, Pointer usw.
// ========
 TYPE
  fmiStatus = (fmiOK,fmiWarning,fmiDiscard,fmiError,fmiFatal);

  fmiCallbackLogger = PROCEDURE(VAR c: fmiComponent; VAR instanceName: fmiString; VAR status: fmistatus;
    VAR category: fmiString; VAR messagex: fmiString) OF OBJECTcdecl;
  fmiCallbackAllocateMemory = PROCEDURE(VAR nobj: size_t; Size: size_t) OF OBJECTcdecl;
  fmiCallbackFreeMemory = PROCEDURE(obj: Pointer) OF OBJECT;  cdecl;

  fmiCallbackFunctions = RECORD
    logger: fmiCallbackLogger;
    allocateMemory: fmiCallbackAllocateMemory;
    freeMemory: fmiCallbackFreeMemory;
  END;


Der Compiler ist zufrieden.
Unsicher bin ich bei der Parameterübergabe (wann Pointer auf den Stack, wann der ganze Inhalt; s.u. in dieser Rubrik). Besonders ist mir mit das Doppelstern-Konstrukt "typedef void* ( *fmiCallbackAllocateMemory)" unklar, ich würde ^PROCEDURE schreiben, was aber natürlich Unsinn ist.

Debuggen ist schwierig, mit Assembler komme ich leidlich zurecht. Aber der Instanziierung-Aufruf ist der komplexeste von alle Funktionsaufrufen, und wenn der nicht geht, dann nützt der Debugger leider bei den einfachen anderen Funktionen nichts.

Umso mehr hoffe ich auf Hinweise.

Grüße
GuaAck
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19313
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 04.02.14 09:47 
of object ist 100%ig falsch. Methoden eines Objektes sind das im Original nicht.

Und von var-Parametern steht im Original auch nichts, die würdest du an dem * für einen Pointer erkennen.

cdecl ist natürlich möglich (EDIT: im Sinne von "könnte dort benutzt worden sein", du musst natürlich das gleiche nutzen), üblicher wäre aber stdcall.

Und ich würde die Typen in Delphi immer mit einem T vorne bezeichnen, einfach um in Delphi sauberen Quelltext zu haben.


Zuletzt bearbeitet von jaenicke am Di 04.02.14 11:04, insgesamt 2-mal bearbeitet

Für diesen Beitrag haben gedankt: GuaAck
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: Di 04.02.14 10:54 
void * ist ein untypisierter pointer. Also etwa
ausblenden Delphi-Quelltext
1:
2:
type
  TfmiCallbackAllocateMemory = function(nobj: size_t; Size: size_t): pointer; stdcall;
was ja auch irgendwie aus dem Namen analog AllocMem vervorgeht (allokiere mir nobj Teile der Größe size), und natürlich keine var parameter, wie schon von user profile iconjaenicke bemerkt.

Für diesen Beitrag haben gedankt: GuaAck
GuaAck Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 378
Erhaltene Danke: 32

Windows 8.1
Delphi 10.4 Comm. Edition
BeitragVerfasst: Mi 05.02.14 23:15 
Danke an beide,

das "of object" war mir bisher nicht wirklich klar, es funktionierte bei mir immer bei der Übergabe von Prodeduren/Functions (in meinen eigene Programmen.) Bei DLLs hatte ich noch nie mit Callback-Funktionen zu tun. Bei der Methode einer Klasse reicht es ja nicht aus, wie bei einer globalen Procedure die Adresse des Codes zu übergeben, es muss ja zusätzlich auch der Context übergeben werden.

cdecl war keine Frage, Standard-C war für die DLL spezifiziert. (klar, das dann auch "of object" sinnlos wäre, hatte ich aber nicht verstanden.)

Auch der * ist mir klarer geworden.

Jedenfalls, das Puzzle ist aufgegangen, Instanzieren mit Nutzung der CallBackfunktionen und Freigabe der Instanz gehen, der Rest ist harmlos. Und ich habe doch Einiges aus Euren "Puzzelsteinen" gelernt.

Danke also und beste Grüße
GuaAck