FPC-Code in C einbinden, error: 0-bit reloc in dll ?

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1251
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

FPC-Code in C einbinden, error: 0-bit reloc in dll ?

Beitrag von corpsman »

Hallo zusammen,

Einen in C geschriebenen Code in FPC ein zu binden ist erfolgreich abgehackt, nun versuche ich mich in der anderen Richtung und kamme aktuell nicht weiter.

Bassierend auf diesem Thread: viewtopic.php?t=9198 muss es ja prinzipiell gehen.

Also habe ich mir erst mal eine Unit gebastelt, welche der Zukünftige C-Code einbinden / ausführen soll:

Code: Alles auswählen

Unit ufpc_to_c;

Interface

uses ctypes;

Function fpc_add(a: cuint16; b: cuint16): cuint16; cdecl; public name{$IFDEF CPU64} 'fpc_add'{$ELSE} '_fpc_add'{$ENDIF};

Implementation

Function fpc_add(a: cuint16; b: cuint16): cuint16; cdecl;
Begin
  result := a + b;
End;

End.
Als nächstes habe ich das ganze Compiliert und erhalte im Unter Ordner "lib\x86_64-win64\ufpc_to_c.o" die gewünschte .o Datei die es ein zu binden geht.

Damit ich das ganze testen kann brauche ich noch die angehängte main.c und eine passende .h Datei:

Code: Alles auswählen

// -------------------------------------------------- ufpc_to_c.h
#ifndef __UFPC_TO_C_H
#define __UFPC_TO_C_H

#include <stdint.h>

uint16_t fpc_add(uint16_t a, uint16_t b);

#endif

// -------------------------------------------------- main.c
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "ufpc_to_c.h"

int main(void)
{
  printf("Demo Application to include FPC-source into a C project\n");

  uint16_t a = 20;
  uint16_t b = 22;
  uint16_t c;

  c = fpc_add(a,b);

  printf("The one and only answer is %d\n", c);

  printf("finished, going down now.\n");
  return 0;
}

Nun will ich das alles zusammen bringen
1. erzeugen der main.o mittels
gcc -c main.c
2. zusammenfügen der beiden .o Dateien zu einem executable
gcc -o test.exe main.o ufpc_to_c,o
Aber anstatt mir das .exe file zu erzeugen bekomme folgende Fehlermeldung:
$ gcc -o test.exe main.o ufpc_to_c.o
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: error: 0-bit reloc in dll
collect2: error: ld returned 1 exit status
Das internet sagt dazu folgendes:
The error message is produced when the linker is attempting to
translate the relocations in the input files into the PE required
format and it encounters a relocation type that it does not
recognise. In this case it would appear that the linker is
encountering a null reloc. (ie one that has already been processed).
=> irgendwas mache ich noch falsch, aber was und wie repariere ich es ?
--
Just try it

Socke
Lazarusforum e. V.
Beiträge: 2968
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: FPC-Code in C einbinden, error: 0-bit reloc in dll ?

Beitrag von Socke »

Zum Thema "relocate" fällt mir der Compiler Schalter -WR (Projekteinstellungen / Compilereinstellungen / Kompilieren und Linken) ein.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1251
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: FPC-Code in C einbinden, error: 0-bit reloc in dll ?

Beitrag von corpsman »

Also nach ein wenig googlen kommt man hier raus:

https://stackoverflow.com/questions/382 ... ic-library

Damit ergibt sich folgende Commandozeile um an die .o Datei zu kommen:
fpc -Cn -CcCDECL -O2 -Xs -XS -Xt ufpc_to_c.pas
Damit der Compiler damit glücklich ist musste ich den Code anpassen zu:

Code: Alles auswählen

Unit ufpc_to_c;

Interface

uses ctypes;

Function fpc_add(a: cuint16; b: cuint16): cuint16; cdecl; public name{$IFDEF CPU64} 'fpc_add'{$ELSE} '_fpc_add'{$ENDIF};

Implementation

Function fpc_add(a: cuint16; b: cuint16): cuint16; cdecl;
Begin
  fpc_add := a + b;
End;

End.

Dann kommt beim aufruf von
gcc -o test.exe main.o ufpc_to_c.o
Keie Fehlermeldung mehr.
Doch wenn ich die .exe ausführe gibt es leider keine Ausgabe auf die Konsole, es geschieht eigentlich gar nichts :(
=> irgendwas ist wohl doch noch falsch ...
--
Just try it

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1251
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: FPC-Code in C einbinden, error: 0-bit reloc in dll ?

Beitrag von corpsman »

Socke hat geschrieben:
Do 11. Nov 2021, 10:50
Zum Thema "relocate" fällt mir der Compiler Schalter -WR (Projekteinstellungen / Compilereinstellungen / Kompilieren und Linken) ein.
Nope bringt nichts, selber fehler ...
--
Just try it

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1251
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: FPC-Code in C einbinden, error: 0-bit reloc in dll ?

Beitrag von corpsman »

Also nun geht es, zumindest mit dem Makefile das ich gerade gebastelt habe
fpc -Cn -CcCDECL -O2 -Xs -XS -Xt ../ufpc_to_c.pas
gcc -c main.c
gcc -o $(APPNAME) main.o ../ufpc_to_c.o
Wenn ich die .o Datei durch "compilieren" mittels Lazarus erzeuge dann knallts -> das Lazarusprojekt muss wohl noch anders eingestellt werden, aber Prinzipiell geht es :D
--
Just try it

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1251
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: FPC-Code in C einbinden, error: 0-bit reloc in dll ?

Beitrag von corpsman »

So nachdem es ja nun funktioniert hat habe ich ein wenig damit herumgespielt,
das Problem scheint die Optimierung zu sein. Es muss mindestens das Optimierungslevel -O2 oder höher gesetzt werden.

Per Default ist mein Lazarus auf O1 gestellt und deswegen hat es nicht geklappt.

Hier mal die Aufdröselung und Reduktion auf das mindeste was ich setzten musste damit es geht.
# siehe: https://www.freepascal.org/docs-html/user/userap1.html
# -Cn = Omit Linking Stage
# -CcCDECL = Set default calling Convention to CDECL
# -O2 = Optimierungslevel muss mindestens 2 sein sonst geht es nicht
# -Xs = Debugger Symbole entfernen
# -XS = Try to link units statically
# -Xt = Link with static libraries
# fpc -Cn -CcCDECL -O2 -Xs -XS -Xt ../ufpc_to_c.pas
fpc -O2 ../ufpc_to_c.pas
gcc -c main.c
gcc -o $(APPNAME) main.o ../ufpc_to_c.o
# gcc -o $(APPNAME) main.o ../lib/x86_64-win64/ufpc_to_c.o <-- Das ist wenn man das .o feile durch lazarus erstellt nimmt, da muss aber dan -O2 drin sein sonst geht es nicht !
Was aber leider nicht geht ist das Debuggen mittels GDB.
Ohne den FPC include kann mein vscode das problemlos, mit beendet es die Anwendung direkt beim Versuch sie zu debuggen, ganz ideal ist es also noch nicht :roll:
--
Just try it

Antworten