Wie wird in einer Sprache geschriebener Code aus einer anderen Sprache aufgerufen?

7

Dies ist eine Frage, die ich schon immer wissen wollte, aber nie wirklich gefragt habe.

Wie wird der von einer Sprache geschriebene Code, insbesondere eine interpretierte Sprache, durch Code aufgerufen, der von einer kompilierten Sprache geschrieben wurde.

Sagen wir zum Beispiel, ich schreibe ein Spiel in C ++ und ich verliere etwas von dem AI-Verhalten, das in Scheme geschrieben werden soll. Wie kommt der in Scheme geschriebene Code zu einem Punkt, der vom kompilierten C ++ - Code verwendet werden kann? Wie wird es vom C ++ - Quellcode verwendet und wie wird es vom kompilierten C ++ - Code verwendet? Gibt es einen Unterschied in der Art, wie es benutzt wird?

Verwandte

  

Wie interagieren mehrere Sprachen in einem Projekt?

    
Hooray Im Helping 08.05.2009, 17:15
quelle

7 Antworten

13

Es gibt keine einzige Antwort auf die Frage, die überall funktioniert. Im Allgemeinen lautet die Antwort, dass sich die beiden Sprachen auf "etwas" einigen müssen - eine Menge oder Regeln oder ein "Rufprotokoll".

Auf einer hohen Ebene muss jedes Protokoll drei Dinge spezifizieren:

  • "Entdeckung": wie man über einander findet.
  • "linking": Wie man die Verbindung herstellt (nachdem sie voneinander wissen).
  • "Invocation": Wie man sich gegenseitig Anfragen stellt.

Die Details hängen stark vom Protokoll selbst ab.

Manchmal arbeiten die beiden Sprachen zusammen, um zusammenzuarbeiten. Manchmal stimmen die zwei Sprachen überein, ein von außen definiertes Protokoll zu unterstützen. Heutzutage ist oft auch das Betriebssystem oder die "Laufzeitumgebung" (.NET und Java) involviert. Manchmal geht die Fähigkeit nur in eine Richtung ("A" kann "B" rufen, aber "B" kann nicht "A" rufen).

Beachten Sie, dass dies das gleiche Problem ist, mit dem jede Sprache bei der Kommunikation mit dem Betriebssystem konfrontiert wird. Der Linux-Kernel ist nicht in Scheme geschrieben, weißt du!

Sehen wir uns einige typische Antworten aus der Windows-Welt an:

  • C mit C ++ : C ++ verwendet eine verzerrte ("mangled") Variante des "C-Protokolls". C ++ kann in C aufrufen und C kann in C ++ aufrufen (obwohl die Namen manchmal recht unordentlich sein können und externe Hilfe benötigt wird, um die Namen zu übersetzen). Dies ist nicht nur Windows; Dies gilt im Allgemeinen für alle Plattformen, die beide unterstützen. Die meisten populären Betriebssysteme verwenden auch ein "C-Protokoll".

  • VB6 vs. die meisten Sprachen : Die bevorzugte Methode von VB6 ist das "COM-Protokoll". Andere Sprachen müssen in der Lage sein, COM-Objekte zu schreiben, die aus VB6 verwendbar sind. VB6 kann auch COM-Objekte erzeugen (obwohl nicht jede mögliche Variation von COM-Objekten).

    VB6 kann auch eine sehr begrenzte Variante des "C-Protokolls" sprechen und dann nur Anrufe außerhalb tätigen: Es kann keine Objekte erzeugen, mit denen direkt über das "C-Protokoll" gesprochen werden kann.

  • .NET-Sprachen : Alle .NET-Sprachen kommunizieren kompilieren in die gleiche Sprache (IL). Die Laufzeit verwaltet die Kommunikation und von diesem Standpunkt aus sehen sie alle wie die gleiche Sprache aus.

  • VBScript und andere Sprachen : VBScript kann nur eine Teilmenge des COM-Protokolls sprechen.

Noch ein Hinweis: SOAP "Web Services" ist auch ein "Anrufprotokoll", wie viele andere webbasierte Protokolle, die immer beliebter werden. Es geht schließlich darum, mit Code zu sprechen, der in einer anderen Sprache geschrieben ist (und in einer anderen Box läuft!)

    
Euro Micelli 08.05.2009, 17:50
quelle
4

Normalerweise ruft der C ++ - Code einen Interpreter für die Skriptsprache auf. Der Grad der Interaktion zwischen dem kompilierten und dem Scripting-Code hängt vom Interpreter ab, aber es gibt immer eine Möglichkeit, Daten zwischen den beiden zu übertragen. Abhängig vom Interpreter kann es möglich sein, die Objekte auf der einen Seite von der anderen Seite zu manipulieren, wie zum Beispiel eine C ++ - Funktion, die eine Methode auf einem Ruby-Objekt aufruft. Es kann sogar eine Möglichkeit geben, die Ausführung der einen von der anderen zu steuern.

    
Pesto 08.05.2009 17:20
quelle
4

Es gibt ein Protokoll für die Kommunikation der Module. Hier ist ein allgemeiner Überblick über die Funktionsweise:

  1. Eine Bibliothek wird für Code erstellt, den Sie teilen möchten. Diese werden normalerweise DLLs oder SOs genannt, abhängig von Ihrer Plattform.
  2. Jede Funktion, die Sie veröffentlichen möchten (Eintrittspunkt), steht der Außenwelt zur Verfügung, an die sie sich binden kann. Es gibt Protokolle zum Binden, wie zum Beispiel die Aufrufkonvention, die die Reihenfolge angibt, in der die Parameter übergeben werden, wer den Stapel aufräumt, wie viele Parameter in Registern gespeichert werden und welche usw. Siehe Beispiele für den Aufruf von cdecl, stdcall usw. Konventionen hier .
  3. Das aufrufende Modul wird dann entweder statisch oder dynamisch an die gemeinsam genutzte Bibliothek gebunden.
  4. Sobald Ihre aufrufende Bibliothek an die gemeinsam genutzte Bibliothek gebunden ist, kann sie angeben, dass sie an einen bestimmten Einstiegspunkt binden möchte. Dies geschieht in der Regel über den Namen, aber die meisten Plattformen bieten auch die Möglichkeit, per Index zu binden (schneller, aber spröder, wenn sich Ihr Modul ändert und die Eingangspunkte neu geordnet werden).
  5. Sie werden die Funktion, die Sie aufrufen möchten, auch generell irgendwo in Ihrem Modul deklarieren, so dass Ihre Sprache eine statische Typprüfung durchführen kann, weiß, wie die Aufrufkonvention ist usw.

Für Ihr Szenario, in dem Sie Scheme aus C ++ aufrufen, exportiert der Scheme-Interpreter höchstwahrscheinlich eine Funktion, die dynamisch an eine Scheme-Funktion / ein Schema bindet und diese aufruft. Wenn das Scheme-Modul kompiliert wird, hat es wahrscheinlich die Möglichkeit, einen Einstiegspunkt zu exportieren, damit Ihr C ++ - Modul daran binden kann. Ich bin mit Schema nicht sehr vertraut, so dass jemand anders die Spezifik dieser bestimmten Bindung wahrscheinlich besser beantworten kann als ich.

    
Adam Markowitz 08.05.2009 17:29
quelle
2

Sie können die beiden Umgebungen auch integrieren, ohne die Bibliothek des Interpreters in Ihrer ausführbaren Datei kompilieren zu müssen. Sie behalten Ihre exe und die Scheme exe als separate Programme auf Ihrem System. Von Ihrer Haupt-Exe können Sie Ihren Scheme-Code in eine Datei schreiben und dann system () oder exec () verwenden, um den Schedule-Interpreter auszuführen. Sie parsen dann die Ausgabe des Schema-Interpreters.

Der oben vorgeschlagene Ansatz hält die Exes getrennt und Sie müssen sich keine Sorgen über Abhängigkeiten von Drittanbietern machen, sie können signifikant sein. Auch Probleme bleiben in der einen oder anderen exe enthalten.

Wenn das Ausführen einer separaten EXE nicht Ihren Leistungsanforderungen entspricht, können Sie ein Protokoll erstellen, bei dem der Scheme-Interpreter ein Server wird. Sie müssen einige Scheme-Funktionen schreiben, die auf eine Eingabe auf einem Socket oder einer Datei warten, eval, dass die Eingabe dann das Ergebnis an denselben Socket oder eine andere Datei ausgibt. Eine weitere Iteration besteht darin, vorhandene Server zu betrachten, auf denen Ihr Interpreter möglicherweise bereits ausgeführt wird. Apache verfügt beispielsweise über Module, mit denen Code in vielen Sprachen geschrieben werden kann.

    
Marius Seritan 08.05.2009 17:37
quelle
1

Wenn Sie tatsächlich nach Tools suchen, um so etwas zu tun, eine Antwort von la Adam, sehen Sie sich Schluck an.

    
Matt 08.05.2009 17:34
quelle
1

Wenn Programm A aus Programmsicht Ressourcen (Klasse / Funktionen / etc) aus Programm B verwenden muss, geht es darum, einige Informationen von A nach B weiterzuleiten und einige Informationen zurückzuholen oder einige Aktionen auszuführen. Also muss es einen Weg geben, der von A zur Verfügung gestellt wird, der es A ermöglicht, Informationen weiterzuleiten und Ergebnisse zu erhalten.

In der Praxis liegt es meist auf der Schulter von Sprachen, diesen Prozess zu bewältigen: Die Sprache B (Programm B wird geschrieben) erzeugt ein Protokoll und stellt Ressourcen in B auf eine vordefinierte Weise zur Verfügung, dann Sprache A (Programm A geschrieben ist) wird ein Dienstprogramm / Framework zur Verfügung stellen, das hilft, die exponierten Ressourcen aufzurufen und Ergebnisse gemäß dem B-Protokoll zu erhalten.

Um genauer auf Ihre Frage einzugehen, ist der Prozess für interpretierte Sprachen ziemlich universell. Das Protokoll gehört normalerweise zu den Befehlszeilenparameterzeilen, der HTTP-Anforderung und anderen Möglichkeiten zur Übertragung von Klartext. Nehmen Sie das erste Beispiel, Programm B wird einen Aufruf von HTTP-Anforderung als Eingabe erhalten und die Anfrage von dort weiter verarbeiten. Das tatsächliche Format der Eingabe wird vollständig von Programm B festgelegt.

Dinge wie SOAP und so weiter, sind nur eine Möglichkeit, Programme zu regulieren, um Input in einem gemeinsam vereinbarten Standard zu erhalten.

    
FlyinFish 08.05.2009 20:08
quelle
1

Es ist ein Jahrzehnt oder so, aber ich habe genau das für meinen Senior-Schlussstein getan (Nun, ich baute ein rückpropagierendes neurales Netzwerk in C auf und benutzte ein Schema-Programm, um es zu lehren). Die Version von Schema, die ich benutzte, hatte einen Compiler und einen Interpreter, und ich konnte es als .o-Datei erstellen. Ich kenne die Version des Schemas, das ich ausgeführt habe, nicht, aber es scheint, dass das RScheme Ihren Schemacode in C umwandelt.

    
Matt Poush 08.05.2009 20:26
quelle