Lazarus static link c_obj files

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Acia6850
Beiträge: 15
Registriert: Mo 9. Okt 2023, 18:45
OS, Lazarus, FPC: Windows + WSL / Linux Debian Rasbian OS (L 3.0.0 FPC 3.3.2)
CPU-Target: 64Bit
Wohnort: LK Ludwigsburg

Lazarus static link c_obj files

Beitrag von Acia6850 »

Ich habe ein kleines c obj File in welchem die function fabs in C gebraucht wird.

double fabs (double x);

die Function ist in C in der math.h deklariert.

wenn man eine C dll darum baut kan man die Dll in Lazarus aufrufen.

Ich möchte aber die C functionen mit der fabs function in Lazarus statisch linken.
Die Idee dahinter,
das C File ist eine C Function Lib welche ich nicht in Pascal übersetzen will, sondern wenn es geht ohne Umweg über eine Dll in eine Lazarus Exe statisch linken möchte.

Ohne die funktion c fabs geht alles.
Leider kann ich die libm nicht in Lazarus einbinden weil ich sie nicht finde.

Die Idee war nun die c fabs Funktion in Lazarus zu schreiben und die c fabs Function zu ersetzen.

zB. function laz_fabs(x : double) : double; cdecl; external;

ich habe ein Header File in C erzeugt mit der Lazarus Funktion

Im gcc läst sich der Code übersetzen.

Aber beim linken der C_obj Datei gibt es in Lazarus einen Linker Error

cLazCObj.lpr(42,1) Error: Undefined symbol: _Z8laz_fabsd !

function laz_fabs(x : double) : double; cdecl; external;
begin
Result := Abs(x);
end;

Ich habe shon versucht die Funtion auf den Namen umzubenennen. (leider kein Erfolg)

In delphi habe ich es schon einmal mit 32 Bit erfolgreich gemacht.

Frage:

Ist es auch in Lazarus in 64Bit möglich ?

Und wie müsste die Funktion in Lazarus und C deklariert werden.



Compiler : Lazarus 2.20 64 Bit
TDM-gcc 9.2.0 64 Bit

Ich freue mich auf die Vorschläge.

Grüße Acia6850

Mathias
Beiträge: 6209
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Lazarus static link c_obj files

Beitrag von Mathias »

cLazCObj.lpr(42,1) Error: Undefined symbol: _Z8laz_fabsd !

function laz_fabs(x : double) : double; cdecl; external;
begin
Result := Abs(x);
end;
Evtl. ein Tipfehler.
Einmal hast du ...fabsd und das andere mal ...fabs

Mit Windows habe ich keine Erfahrung, aber unter Linux ist es sehr wichtig die Gross und Kleinschreibung zu beachten.
Aber das könnte auch unter Windows ein Problem sein, der C-Compiler beachtet dies dort auch.

Steht bei dir auch so etwas in dieser Art am Anfang deines Programmes ?
Achtung xxx.o, ist Linux.

Code: Alles auswählen

{$L xevent_type.o}  
{$LinkLib c}
Oder du gibst den lib-Name direkt hinter external an.
Hier ein Beispiel mit printf.

Code: Alles auswählen

const
  lib_stdio='c';
...  
function printf(str:PChar):cint;varargs cdecl;external lib_stdio;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: Lazarus static link c_obj files

Beitrag von theo »

Sieht nach C++ Name Mangling aus. Damit kann FPC nichts anfangen.
Mache im C++ Code:

Code: Alles auswählen

extern "C" {

}
Siehe: https://downloads.freepascal.org/fpc/do ... Pascal.pdf

Acia6850
Beiträge: 15
Registriert: Mo 9. Okt 2023, 18:45
OS, Lazarus, FPC: Windows + WSL / Linux Debian Rasbian OS (L 3.0.0 FPC 3.3.2)
CPU-Target: 64Bit
Wohnort: LK Ludwigsburg

Re: Lazarus static link c_obj files

Beitrag von Acia6850 »

Hallo hier der Test Code.

Funtioniert irgenwie nicht.

Gruß Acia6850
Dateianhänge
Forum.zip
(4.06 MiB) 84-mal heruntergeladen

Mathias
Beiträge: 6209
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Lazarus static link c_obj files

Beitrag von Mathias »

Dies sieht ein wenig merkwürdig aus.

Code: Alles auswählen

  {$Linklib ..\Lib\x86_64-win64\libmsvcrt.a}
  {$Linklib ..\lib\x86_64-win64\kernel32.a}
  {$Linklib ..\lib\x86_64-win64\libgcc.a}
Wen ich zB. in GTK2.pas reingucke. sieht dies ganz anders aus.

Code: Alles auswählen

  gtklib = 'libgtk-win32-2.0-0.dll';
Ich würde mal probieren, ob du erst mal eine HelloWorld mit printf() hinkriegst.

Code: Alles auswählen

Const
  clib = 'c';

function printf(__format:PAnsiChar; args:array of const):longint;cdecl;external clib name 'printf';

begin
  printf('Hello World', []);  
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Acia6850
Beiträge: 15
Registriert: Mo 9. Okt 2023, 18:45
OS, Lazarus, FPC: Windows + WSL / Linux Debian Rasbian OS (L 3.0.0 FPC 3.3.2)
CPU-Target: 64Bit
Wohnort: LK Ludwigsburg

Re: Lazarus static link c_obj files

Beitrag von Acia6850 »

Hallo Mathias so läuft es ohne die fabs Funktion.

C Code

#ifndef XLAZCDEF_H
#define XLAZCDEF_H

#include <stdio.h>
#include <string.h>


// double laz_fabs(double x);

extern "C" void xView();


#endif

#include <xLazCDef.h>


void xView()
{
puts("C_Obj HomeControlCObj.lib");

// printf("%fd", laz_fabs(-45.78));
}

Lazarus Code

program cLazCObj;


{$IFDEF FPC}
{$MODE DELPHI}

{$H+} (* use AnsiString *)
{$PACKENUM 4} (* use 4-byte enums *)
{$PACKRECORDS C} (* C/C++-compatible record packing *)
{$ELSE}
{$MINENUMSIZE 4} (* use 4-byte enums *)
{$ENDIF}


uses
{$IFDEF LINUX}
cthreads,
{$ENDIF}
Sysutils, Classes;


{$IFDEF WIN64}
// {$Link ..\Lib\x86_64-win64\xLazCDeCf.o}
{$Link ..\Lib\x86_64-win64\xLazCDef.o}

{$Linklib ..\Lib\x86_64-win64\libmsvcrt.a}
{$Linklib ..\lib\x86_64-win64\kernel32.a}
{$Linklib ..\lib\x86_64-win64\libgcc.a}
{$ENDIF}


procedure xView(); cdecl; external;

{
function laz_fabs(x : double) : double; cdecl;
begin
result := Abs(x);
end;
}

procedure xRun;
begin
WriteLn('cLazCObj Demo');
xView;
end;

begin
xRun;
end.

Nur wie bringe ich Lazarus und C bei die laz_fabs funktion für c fabs zu ersetzen damit ich nicht die libm brauche in der ist fabs vorhanden ich kann sie aber nicht in Lazarus einbinden.
Dateianhänge
cLazCObj.exe
(257 KiB) 80-mal heruntergeladen

Mathias
Beiträge: 6209
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Lazarus static link c_obj files

Beitrag von Mathias »

Verstehe ich dich richtig.
Du willst in C eine lib entwickeln, welche man später auch in Lazarus nutzen kann ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Acia6850
Beiträge: 15
Registriert: Mo 9. Okt 2023, 18:45
OS, Lazarus, FPC: Windows + WSL / Linux Debian Rasbian OS (L 3.0.0 FPC 3.3.2)
CPU-Target: 64Bit
Wohnort: LK Ludwigsburg

Re: Lazarus static link c_obj files

Beitrag von Acia6850 »

Hallo Mathias,

ich habe eine größer C-Lib mit vielen Funktionen welche auch die math lib von C benötigen.
Das einbinden als C-Dll ist kein Problem.

Wenn man aber die C-Lib statisch in eine Lazarus Exe linken will benötigt man die libm.
Die finde ich nicht im TDM-gcc Compiler auf Win64.
Da in der C-Lib aber nur 5 C-Functionen die libm benötigen möchte ich die 5 C Functionen in der C Lib mit Lazarus Functionen ersetzen,
damit ich sie ohne libm kompilieren und linken kann.

So kann ich eine Lazarus Exe erstellen ohne C-Dll.

Deshalb habe ich ein kleines Test Program in C und Lazarus geschriebn welches aber leider noch nicht zum Erfolg geführt hat.

Grüße und Danke

Acia6850

Socke
Lazarusforum e. V.
Beiträge: 3158
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: Lazarus static link c_obj files

Beitrag von Socke »

Acia6850 hat geschrieben:
Mo 27. Nov 2023, 16:23
Aber beim linken der C_obj Datei gibt es in Lazarus einen Linker Error

cLazCObj.lpr(42,1) Error: Undefined symbol: _Z8laz_fabsd !

function laz_fabs(x : double) : double; cdecl; external;
begin
Result := Abs(x);
end;
Über den Modifier "external" wird doch angegeben, dass die Funktion in einer externen Bibliothek liegt?

Brauchst du für deine Funktion laz_fabs nicht den Modifier export ggf. in Verbindung mit einem Namen?

Code: Alles auswählen

function laz_fabs(x : double) : double; cdecl; export name '_Z8laz_fabsd';
begin
   Result := Abs(x);
end;/code]
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

PascalDragon
Beiträge: 834
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Lazarus static link c_obj files

Beitrag von PascalDragon »

Mathias hat geschrieben:
Mo 27. Nov 2023, 19:16
Dies sieht ein wenig merkwürdig aus.

Code: Alles auswählen

  {$Linklib ..\Lib\x86_64-win64\libmsvcrt.a}
  {$Linklib ..\lib\x86_64-win64\kernel32.a}
  {$Linklib ..\lib\x86_64-win64\libgcc.a}
Wen ich zB. in GTK2.pas reingucke. sieht dies ganz anders aus.

Code: Alles auswählen

  gtklib = 'libgtk-win32-2.0-0.dll';
Das ist nötig für statisches linken, was Acia6850 möchte.
Mathias hat geschrieben:
Mo 27. Nov 2023, 19:16
Ich würde mal probieren, ob du erst mal eine HelloWorld mit printf() hinkriegst.

Code: Alles auswählen

Const
  clib = 'c';

function printf(__format:PAnsiChar; args:array of const):longint;cdecl;external clib name 'printf';

begin
  printf('Hello World', []);  
Das hier führt zu dynamischem linken, was Acia6850 eben nicht möchte.
Acia6850 hat geschrieben:
Mo 27. Nov 2023, 19:53
Hallo Mathias so läuft es ohne die fabs Funktion.
FPC verwendet ein anderes Mangling als C. Du musst also zum Beispiel public; alias: '_Z8laz_fabsd' nutzen, so dass die Funktion ein passendes Alias hat, das vom C-Code aus genutzt werden kann (nicht getestet, aber in die Richtung sollte es gehen).
FPC Compiler Entwickler

Mathias
Beiträge: 6209
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Lazarus static link c_obj files

Beitrag von Mathias »

Das hier führt zu dynamischem linken, was Acia6850 eben nicht möchte.
Ich dachte, dieses printf wird da auch statisch reingelinkt ?
Oder werden Bibliotheken unter /usr/lib immer dynamisch gelinkt ?
Dies würde eigentlich Sinn machen.
Aber wieso motzt der Linker, wen er eine lib nicht findet, wen es dynamisch ist ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Acia6850
Beiträge: 15
Registriert: Mo 9. Okt 2023, 18:45
OS, Lazarus, FPC: Windows + WSL / Linux Debian Rasbian OS (L 3.0.0 FPC 3.3.2)
CPU-Target: 64Bit
Wohnort: LK Ludwigsburg

Re: Lazarus static link c_obj files

Beitrag von Acia6850 »

Vielen Dank für Eure Hilfe, es funktioniert mit folgendem Code

function laz_fabs(x : double) : double; cdecl; export;
begin
Result := Abs(x);
end;

Ich habe es schon umgesetzt und die c-Lib (Berechnung von Astrodaten) eingebunden

Grüße Acia6850.

PascalDragon
Beiträge: 834
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Lazarus static link c_obj files

Beitrag von PascalDragon »

Mathias hat geschrieben:
Mi 29. Nov 2023, 14:04
Das hier führt zu dynamischem linken, was Acia6850 eben nicht möchte.
Ich dachte, dieses printf wird da auch statisch reingelinkt ?
Nein, die Syntax external <LIBRARY> name <NAME> ist immer für dynamisches Linking. Für statisches Linken muss einfach nur external allein angegeben werden zusammen mit einem {$linklib <LIBRARY>}.
Mathias hat geschrieben:
Mi 29. Nov 2023, 14:04
Oder werden Bibliotheken unter /usr/lib immer dynamisch gelinkt ?
so-Dateien werden immer dynamisch gelinkt. Ob bei gleichnamigen Bibliotheken (libxyz.so und libxyz.a) die dynamische oder statische gelinkt wird hängt in Pascal von eben den obigen Syntaxen entschieden.
Mathias hat geschrieben:
Mi 29. Nov 2023, 14:04
Aber wieso motzt der Linker, wen er eine lib nicht findet, wen es dynamisch ist ?
Weil es für das ELF Format im Gegensatz zum PE Format notwendig ist, dass die Zielbibliothek zum Zeitpunkt des Linkens verfügbar ist.
FPC Compiler Entwickler

Mathias
Beiträge: 6209
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Lazarus static link c_obj files

Beitrag von Mathias »

Nein, die Syntax external <LIBRARY> name <NAME> ist immer für dynamisches Linking. Für statisches Linken muss einfach nur external allein angegeben werden zusammen mit einem {$linklib <LIBRARY>}.
Ich dachte immer dies mache das gleiche, $linklib diene nur dazu, das man die lin nicht bei jeder function angeben muss.
Aber anscheinend habe ich mich getäuscht.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 834
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Lazarus static link c_obj files

Beitrag von PascalDragon »

Mathias hat geschrieben:
Sa 2. Dez 2023, 12:55
Nein, die Syntax external <LIBRARY> name <NAME> ist immer für dynamisches Linking. Für statisches Linken muss einfach nur external allein angegeben werden zusammen mit einem {$linklib <LIBRARY>}.
Ich dachte immer dies mache das gleiche, $linklib diene nur dazu, das man die lin nicht bei jeder function angeben muss.
Aber anscheinend habe ich mich getäuscht.
Die $LinkLib Direktive kann für beides genutzt werden. Besonders wenn du sowohl eine libXYZ.so und libXYZ.a im Bibliotheksverzeichnis hast, kannst du mit Hilfe von $LinkLib XYZ,static oder $LinkLib XYZ,shared kontrollieren, ob statisch oder dynamisch gelinkt wird. Mit external name <name> kann dann noch der genaue Importname kontrolliert werden, ansonsten reicht auch external. Mit external <lib> name <name> ist es jedoch immer dynamisches Linken.
FPC Compiler Entwickler

Antworten