[gelöst] Mit FPC eine C External Function bedienen ..

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

[gelöst] Mit FPC eine C External Function bedienen ..

Beitrag von corpsman »

Hallo,

ich darf hier Beruflich Lazarus einsetzen obwohl ich Beruflich in C Programmieren muss.

Nun habe ich folgenden C-Code:

Code: Alles auswählen

void system_init(void);
Den kann ich natürlich aus FPC mittels

Code: Alles auswählen

Procedure system_init(void);cdecl; extern;
aufrufen, das funktioniert wunderbar.

Wie geht es aber andersrum, also das ich folgenden C-Code habe:

Code: Alles auswählen

extern void system_dummy(void);
Der dann vom Linker so verknüpft wird das er eine Passende Routine in meinem FPC aufrufen kann.
Probiert habe ich es mittels:

Code: Alles auswählen

Procedure system_dummy(void);cdecl;
Implementation
Procedure system_dummy(void);cdecl;
begin
end;
Dann sagt mir der Linker:

project1.lpr(21,1) Error: Undefined symbol: _system_dummy

Geht das überhaupt ?

Ich meine mich dunkel zu erinnern das man dem Linker namen mitgeben kann aber wie genau ging das noch ...
Zuletzt geändert von corpsman am Do 30. Apr 2020, 10:45, insgesamt 1-mal geändert.
--
Just try it

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

Re: Mit FPC eine C External Function bedienen ..

Beitrag von Mathias »

Willst du auf *.o Dateien zugreiffen, welche mit c compiliert wurden ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

corpsman
Beiträge: 1163
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus SVN Trunk, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Mit FPC eine C External Function bedienen ..

Beitrag von corpsman »

Genau,

der GCC Compiler hat mir den C-Code in .o Dateien umgewandelt.

Diese kann man einbinden und dann wie im ersten Post darauf zugreifen.
--
Just try it

corpsman
Beiträge: 1163
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus SVN Trunk, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Mit FPC eine C External Function bedienen ..

Beitrag von corpsman »

Hah,

ich glaube ich hab es gefunden,

Code: Alles auswählen

https://www.freepascal.org/docs-html/ref/refsu71.html
Wenn ich morgen auf Arbeit bin probiere ich das mal ;)
--
Just try it

Warf
Beiträge: 1529
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: MacOS | Win 10 | Linux
CPU-Target: x86_64
Wohnort: Aachen

Re: Mit FPC eine C External Function bedienen ..

Beitrag von Warf »

Das was du da machst, wird dir wahrscheinlich weniger spaß bereiten als direkt mit C zu arbeiten.

Du darfst nicht vergessen, wenn du verschiedenen Code gegeneinander Linkst, hast du feste boundaries die du nicht überschreiten darfst. So darfst du in einer Code basis keinen Speicher alloziieren den du in der anderen Code basis wieder freigeben willst. Desweiteren dürfen keine Exceptions in die andere Codebasis geleitet werden, du musst also praktisch alles was aus C raus aufgerufen wird (z.b. über callbacks) in Try-Except packen. Außerdem musst du mit Arrays und Strings aufpassen wenn du die zwischen FPC und C code hin und her schiebst, FPC strings und arrays sind referenzgezählt, das weiß C aber nicht. Wenn du also einen String an C übergibst ohne ihn vorher zu kopieren, und dann dein Datenflow endet, wird der FPC code den String free'n und der C code hat nur noch einen Invaliden Pointer. Mal ganz davon abgesehen das du in die Buildsystem hölle schlechthin kommst wenn das C programm nicht trivial sein sollte (und damit selbst schon ein nicht triviales buildsystem haben wird).

Klar ist es möglich, aber ich denke mal das du dabei so viel Zeit verschwendest das es sich nicht wirklich lohnen wird. Du musst halt bei jeder Zeile code 3 mal überlegen ob du das so überhaupt machen kannst oder nicht. Neben den Sachen die ich oben erwähnt habe gibt es bistimmt noch mehr "Fallen" in die man tappen kann, und Fehlerbehandlung/Debugging über mehrere Sprachen hinweg ist absolut beschissen. Mach dich also darauf gefasst mindestens doppelt so lange zu brauchen wegen solch dummen Fehlern.

Wenn man sowas machen will sollte gesichert sein das das Interface zwischen C und Pascal möglichst gering ist, z.b. wie bei einer Library/DLL. Wenn der C code und dein Code sich allerdings parallel entwickeln und stark miteinander verwoben sind wirst du absolut keinen spaß dran haben

corpsman
Beiträge: 1163
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus SVN Trunk, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Mit FPC eine C External Function bedienen ..

Beitrag von corpsman »

@Warf
Prinzipiell gebe ich dir Recht, ich bin aber Embedded Software Entwickler und schreibe nur einen GUI Mockup. Speicher Teile ich nicht, exceptions hat mein C-Code nicht. DIe Einzige Abhängigkeit die ich habe ist zu stdio.h und stdint.h und einen Speicherbereich den ich ganz zu anfang Allokiere und nie freigebe.

In meinen Bisherigen Projekten hat das alles 1a Funktioniert, auch weil mir die Speicher Verwaltungsgeschichten durchaus bewusst sind.

Mein bisher einziges und ungelöstes Problem ist, das ich einen 32-Bit FPC Compiler nehmen muss und entsprechend den C++ Compiler mit -m32 auf 32-Bit zwingen muss. Nutze ich den 64-Bit FPC, dann bekomme ich immer die Meldung dass ettliche Werte Mehrfach definiert seien.
--
Just try it

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

Re: Mit FPC eine C External Function bedienen ..

Beitrag von Mathias »

Du musst bei Lazrus bei Plattform win32 i386 nehmen.
Vorausgesetzt du hast ein 32 Bit Crosscompiler im 64 Bit Lazarus.

Verwendest du win oder Linux ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

corpsman
Beiträge: 1163
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus SVN Trunk, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Mit FPC eine C External Function bedienen ..

Beitrag von corpsman »

Auf der Arbeit muss ich leider Windows 10 nehmen.

Was ich ja nicht verstehe, warum geht es wenn ich einen FPC32-Bit Compiler mit gcc -m32 nehme und der Selbe Code mit einem FPC64-Bit Compiler mit gcc geht nicht, bzw. in Trivialprogrammen geht es. Nur bei den "Größeren" C-Programmen geht es nicht. Da die dann aber gleich rießig sind kann ich nicht genau sagen was die Ursache ist..
--
Just try it

corpsman
Beiträge: 1163
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus SVN Trunk, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Mit FPC eine C External Function bedienen ..

Beitrag von corpsman »

So nachdem es mit dem "External name" auch nicht geht und ich noch viel komischere Fehlermeldungen bekomme habe ich das ganze mal in ein Demo programm gebastellt, so das wer mag das auch bei sich testen kann.

Falls ihr gerade keinen gcc zur Hand habt habe ich das compilierte .o file auch mit ins Zip gepackt.

Code: Alles auswählen

unit c_wrapper;

{$mode objfpc}{$H+}

{$Link c_source.o}

{$LINKLIB libmsvcrt}

interface

uses
  Classes, SysUtils;

Procedure system_init();cdecl external;

Procedure system_call();cdecl external;

implementation

//Procedure system_e_call() cdecl external name '_system_e_call'; // das geht auch nicht
Procedure system_e_call() cdecl external name 'system_e_call';
begin
  writeln('Jessa.');
end. // Warum will der Compiler das ich hier einen Punkt mache ?

end.

Die Compilerfehlermeldung lautet nun:
project1.lpr(21,1) Error: Undefined symbol: _system_e_call
Die c_source.h sieht im prinzip so aus:

Code: Alles auswählen

#ifndef __C_SOURCE_H__
#define __C_SOURCE_H__

void system_init(void);

void system_call(void);

extern void system_e_call(void);

#endif
Dateianhänge
C_Lib_Demo.zip
(239.38 KiB) 45-mal heruntergeladen
--
Just try it

kupferstecher
Beiträge: 285
Registriert: Do 17. Nov 2016, 11:52

Re: Mit FPC eine C External Function bedienen ..

Beitrag von kupferstecher »

Es gibt noch den Alias-Modifier:

function Abc; Alias: '_system_init';

corpsman
Beiträge: 1163
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus SVN Trunk, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Mit FPC eine C External Function bedienen ..

Beitrag von corpsman »

Das wars,

Danke der Alias Funktioniert, das spart mir dann einen Haufen Arbeit.

Vielen Dank ich wusste doch das FPC so etwas kann *g*

[Edit]

Wie hier zu lesen: https://www.freepascal.org/docs-html/ref/refsu70.html
Soll man Alias nicht mehr nehmen und stattdessen "Public name" (siehe: https://www.freepascal.org/docs-html/re ... 0014.10.12 )
das geht dann sogar mir Variablen ;)
--
Just try it

Antworten