Mathias hat geschrieben: Mi 28. Jun 2023, 13:29
Bis jetzt ist mir nur C,C++, Pascal und Assembler bekannt, was sich kombinieren lässt.
Bei Java denke ich es kaum, das dies geht, ausser das Java auf *.o zugreifen kann, oder täusche ich mich da ?
Ich denke, es gibt sicher noch Compiler-Exoten, welche auch gehen.
Das ELF Format ist nur für Native Programmiersprachen relevant, und ist auch Nativ zur Unix Welt. Java oder z.B. C# sind VM basierte Sprachen, die auf einer ganz anderen Architektur basieren (ich glaube häufig stack maschienen), von daher sind die nicht wirklich mit Nativem Code kombinierbar. Es gibt zwar entsprechende Wrapper Möglichkeiten (bei Java die JNI Java-Native-Bridge), das ist aber dann nur für Shared Libraries (,dll, .SO, .dylib) und sind dafür gemacht vom OS zur Laufzeit geladen zu werden (und nicht ins Programm Kompiliert zu werden).
Von den Nativen Sprachen können die meisten Object Files generieren auf eine oder die andere Weise. Bei C und C++ ists klar, immerhin wurde der kram ja für C erfunden. Viele Sprachen heut zu tage benutzen aber LLVM als Backend (der Compiler kompiliert zu LLVM, und LLVM kompiliert das dann zu Maschinencode, ein einfacher weg cross plattform compiler zu bauen), und während du dabei zwar Linking auf LLVM ebene machen kannst, und das für Link Time Optimization (LTO) auch gerne bevorzugt wird, ist das relativ analog aufgebaut, wo einzelne Units zu bitcode files (.bc) kompiliert werden, und die kann man sich mit LLVM auch ganz einfach als Object Files rauswerfen lassen.
Somit kannst du bei den ganzen LLVM Sprachen wie Swift, Rust, Go auch object files rauswerfen.
Außerdem gibt es viele Sprachen die C als zwischenebene benutzen, z.B. Python, Matlab oder Haskell. Hier kannst du dir natürlich auch .o Files rauswerfen lassen.
Also im grunde, wenns einen Nativen Compiler für Unix/Linux gibt, gibts auch Object Files.
Mathias hat geschrieben: Mi 28. Jun 2023, 13:29
Bei miti C erstellten *.o muss man aufpassen, das man FPC-Seitig "cdecl" hinschreibt. Anscheinend doch nicht 100% kompatibel ?
Das ist tatsächlich das Hauptproblem, die Sprachen müssen Kompatibel sein. Wenn du C in Pascal einbindest müssen die Datenstrukturen gleich aufgebaut sein, und die Funktionen gleich aufgerufen werden. Mit C ist das extrem einfach, denn C hat hier im grunde alle Standards gesetzt, undzwar im Buchstäblichen Sinne. Da durch das C standardisiert ist und es so eine unglaublich erfolgreiche Programmiersprache war/ist, gibt es wohldefinierte wege in ziemlich allen sprachen C code einzubinden.
Z.B. unterstützt Pascal die C-DECLaration calling convention "cdecl", sowie records sind (zumindest mit {$PackRecords C} ) fast vollständig Kompatibel zu C structs.
Wenn C nicht so dominant gewesen wäre, und die Programmiersprachen Landschaft nur ein bisschen Diverser gewesen wäre, wäre das vermutlich nicht so einfach möglich.
Problematisch wird es nur wenn Sprachen Features haben die man so einfach abbilden kann. Wenn man z.B. mit C++ schon anfängt, das Speicherlayout (OOP) von Klassen ist (im gegensatz zu C Structs) nicht Standardisiert. Zwar sind Clang und GCC auf einer linie und MSVC++ ist wohl dokumentiert, aber d.h. nicht das es mit allen C++ compilern so einfach ist. Z.B. wenn man QT mit Intel C++ benutzen will muss man das SDK neu Kompilieren, weil die Precompilierte Version nicht damit Kompatibel ist.
Bei anderen Sprachen kommen noch weitere sachen hinzu. Exceptions, Co-routinen, Lambdas, Generics, etc. für all diese sprach konstrukte gibt es keine etablierten Standards, und damit nicht einfach den weg diese Sprachen in anderen Sprachen einzubinden.
Selbst mit Strings geht das schon auseinander. Pascal ShortStrings sind anders zu AnsiStrings sind anders im vergleich zu C++ Strings und ganz anders zu den alten C-PChar strings. Daher braucht man beim benutzen von C bibliotheken immer das doofe hin und her convertiere zwischen PChar und String. Oder Exceptions gibt es nicht in jeder Sprache und das ist warum man keine Exceptions über DLL grenzen hinweg werfen darf, etc.
Es ist erstaunlich wie viel geht, und dafür ist wohl Hauptsächlich der Erfolg von C verantwortlich, aber die liste mit Dingen die nicht gehen ist vermutlich deutlich länger