Bibliothek für C und Pascal schreiben

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Bibliothek für C und Pascal schreiben

Beitrag von Socke »

theo hat geschrieben:
Targion hat geschrieben:Wenn ich also sowas habe:

Code: Alles auswählen

TMessageEvent = procedure(Sender: TObject;msg: String) of object;
function remove_app(aid: String; msg: TMessageEvent; fast: Boolean=false;
Kann ich das 1:1 in der Lib nutzen, und in C wie in Pascal einfach die Adresse der Prozedur übergeben?
"of object" schon mal nicht.
Das muss eine normale Prozedur sein:

procedure Test(inp:Pchar); cdecl;
begin
//blah
end;

MeinRegisterCallbackInC(@Test);

Glaub ich auf die Schnelle ;-)
Ich bin der Meinung, dass man auch Methoden (nicht nur Prozeduren und Funktionen) verwenden kann. Da ein of object; aber in einem Record (TMethod) endet, muss man diesen ve-rarbeiten.
Was mir beim Übersetzen der libgio-Header-Dateien aufgefallen ist, ist, dass man die Methoden auch direkt als Funktions-Zeiger verwenden kann; man muss dann nur ein bisschen aufpassen.

Code: Alles auswählen

function TMyObject.DoSth(param: PChar): Integer; cdecl;
// wäre mit 
TMethod(@TMyObject.DoSth).Code;
// als Funktionszeiger zugänglich
Zusätzlich muss man dies in einer abgeflachten API aber als

Code: Alles auswählen

TDoSthFunc = function (Self: TObject; param: PChar): Integer; cdecl;
oder in C:

Code: Alles auswählen

typedef _fpcobject fpcobject; /* als dummy record um Zeiger darauf verwenden zu können */
typedef long (*tdosthfunc) (Self *fpcobject; param *Char);
So müsste das in etwa mit callbacks funktionieren; wie man Methoden in Biblitheken exportiert kann ich noch nicht wirklich beantworten (solange nicht alles manuell gemacht wird).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

Re: Bibliothek für C und Pascal schreiben

Beitrag von Targion »

Was exportiere ich denn dann in der Lib im exports-Teil? Einmal die Funktion, welche die Adresse der Funktion erwartet und dann?
Wie sage ich der C-Anwendung, welche Parameter die Funktion benötigt?

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Bibliothek für C und Pascal schreiben

Beitrag von Socke »

Targion hat geschrieben:Was exportiere ich denn dann in der Lib im exports-Teil? Einmal die Funktion, welche die Adresse der Funktion erwartet und dann?
Wie sage ich der C-Anwendung, welche Parameter die Funktion benötigt?
Damit die C-Anwndung weiß, welche Paramter der Callback-Funktion übergeben werden müssen, muss die Funktion dort nur deklariert werden. Das ist wie in Pascal, du schreibst einfach die Funktion mit der Parameterliste hin.

Damit die Bibliothek den Callback aufrufen kann, muss die Bibliothek diesen auch kennen. Üblicherweise gibt es eine Funktion, die den Funktionszeiger entgegen nimmt.

Also für eine einfache Callback-Funktion sollte so aussehen (Bibliothek in Pascal):

Code: Alles auswählen

// der Funktionstyp
type
  TCallback = function (param1: PChar; param2: longint): longint; cdecl;
// eine Variable zum speichern der Adresse
var call: TCallback;
 
// die Funktion zum Registrieren; muss deshalb in den exports-Abschnitt
procedure RegisterCallback(callback: TCallback);
begin
  // die Callback-Adresse irgendwo zwischen speichern; (ich bin mir bei dem @ nicht sicher, müsste aber so sein)
  call := @callback;
end;
 
// und aufrufen geht so:
procedure CallCallback;
var i: longint;
begin
// funktioniert wie jeder andere Funktionszeiger auch
  i := call('abc',5);
end;
In C sollte die Header-Datei so aussehen:

Code: Alles auswählen

/* Der Callback-Funktions-Typ; hier bin ich mir mit den integer-Typen nicht sicher. Den musst du aber nur Deklarieren, wenn du irgendwo Variablen mit Funktionszeigern im C-Programm speichern willst. */
typedef long (*tcallback) (Char *param1, long param2);
 
/* die register-prozedur aus der Bibliothek importieren */
void RegisterCallback (tcallback callback); 
 
/* du musst dann eigentlich nur noch deine Funktion schreiben... */
long my_callback_func (Char *param1, long param2) {
}
 
/* ...und zum Registrieren musst du nur den Funktionszeiger übergeben; von der Syntax weiß ich nichts, aber in Pascal wäre das ein RegisterCallback(@my_callback_func) */
  RegisterCallback (my_callback_func);
hoffe das hilft, auch wenn sich mein C auf das übersetzen von Header-Dateien beschränkt :oops:
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

Re: Bibliothek für C und Pascal schreiben

Beitrag von Targion »

Okay, ich werde für meine Lib mal eine Testanwendung schreiben. Hoffentlich funktioniert das! Danke für die Hilfe! :mrgreen:

EDIT: Jup, läuft wie geschmiert in einer Pascal-Anwendung. Mit C teste ich erst, wenn alles fertig ist.

Antworten