Wie kann ich eine Reihe von Funktionen schreiben, die in (fast) jeder Programmiersprache aufgerufen werden können?

33

Ich möchte einen Weg finden, eine API zu schreiben, auf die von jeder anderen Programmiersprache über Sprachbindungen (oder ein anderes Framework) zugegriffen werden kann. Ist das möglich? Wenn ja, welche Programmiersprache eignet sich am besten zum Schreiben einer "sprachübergreifenden" API? Mein Ziel ist es, einen einzigen Satz von Funktionen zu erstellen, auf die ich von jeder Programmiersprache aus zugreifen kann, mit der ich arbeite, damit ich nicht die gesamte API in jeder Sprache manuell neu schreiben muss.

Anderson Green
quelle
4
Wenn Sie nur aus Marketinggründen sagen möchten, dass wir ALLES unterstützen, können Sie einfach eine DLL auf niedriger Ebene oder eine gemeinsam genutzte Bibliothek in C schreiben Besser eine Java-Schnittstelle bereitstellen.
mjfgates
1
Sie sagen "(fast) alle", welche Sprachen würden Sie für diesen Zweck ausschließen? Oder welche sind Ihnen am wichtigsten?
Funkybro
22
Internetservice? Sie können einige Funktionen in PHP schreiben. Fast jede Sprache hat die Möglichkeit, mit Webseiten zu kommunizieren, Argumente zu liefern und die Ergebnisse zu lesen.
Pieter B
7
+1, weil es eine interessante Frage ist - aber Ihre Frage würde sich verbessern, wenn Sie angeben, warum Sie dies tun möchten. Was sind deine Ziele?
TarkaDaal,
@PieterB => antworte.
Konrad Rudolph

Antworten:

44

Sie haben einige Möglichkeiten:

  1. Erstellen Sie eine HTTP-Schnittstelle, mit der fast alle HTTP-fähig sind, sodass Sie viele Sprachen erhalten.

  2. Erstellen Sie etwas, das in eine Sprachlaufzeit eingebunden werden kann. Dies ist recht zeitaufwendig, da Sie einen Weg finden müssen, um es mit vielen verschiedenen Sprachen zu verbinden.

Zachary K
quelle
Welche Art von HTTP-Schnittstelle haben Sie speziell im Sinn?
Anderson Green
@AndersonGreen Es sollte keine Rolle spielen (da jede Sprache, die einen Netzwerk-Socket öffnen kann, HTTP sprechen kann), aber REST ist ein nützlicher Pseudostandard.
Setzen Sie Monica
7
REST + JSON wäre eine vernünftige Lösung
David Hayes
Ich stimme auch zu, dass die Verwendung von HTTP zur Kommunikation so gut wie jeder Sprache die Interaktion mit den Funktionen Ihrer Anwendung ermöglicht.
Nur Bolivianer hier
30

Ich denke, C oder C ++ wären für Ihren Zweck am besten geeignet. Mit SWIG (Simplified Wrapper and Interface Generator) können Sie Sprachbindungen aus Ihrer C- oder C ++ - API generieren.

SWIG ist ein Software-Entwicklungstool, das in C und C ++ geschriebene Programme mit einer Vielzahl von Programmiersprachen auf hohem Niveau verbindet. SWIG wird mit verschiedenen Arten von Zielsprachen verwendet, einschließlich gängiger Skriptsprachen wie Perl, PHP, Python, Tcl und Ruby. Die Liste der unterstützten SprachenEnthält auch Nicht-Skriptsprachen wie C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), D, Go-Sprache, Java einschließlich Android, Lua, Modula-3, OCAML, Octave und R. Auch mehrere interpretierte und kompilierte Scheme Implementierungen (Guile, MzScheme / Racket, Chicken) werden unterstützt. SWIG wird am häufigsten zum Erstellen von hoch interpretierten oder kompilierten Programmierumgebungen, Benutzeroberflächen und als Tool zum Testen und Prototypen von C / C ++ - Software verwendet. SWIG wird in der Regel zum Analysieren von C / C ++ - Schnittstellen und zum Generieren des für den Aufruf des C / C ++ - Codes in den oben genannten Zielsprachen erforderlichen "Glue-Codes" verwendet. SWIG kann seinen Analysebaum auch in Form von XML- und Lisp-s-Ausdrücken exportieren. SWIG ist freie Software und der Code, den SWIG generiert, ist mit kommerziellen und nichtkommerziellen Projekten kompatibel ...

LMC
quelle
32
C ++ wäre eine schreckliche Wahl. Es gibt zahlreiche Probleme: Abhängigkeit von einer Laufzeitbibliothek, nicht spezifiziertem ABI (insbesondere Mangling) usw. Das Generieren von Bindings aus C ++ - Headern ist unerschwinglich schwierig. SWIG ist eine ziemlich begrenzte Sache. Sehen Sie sich beispielsweise die gesamte überkomplizierte Infrastruktur rund um Python Qt-Bindungen an.
SK-logic
14
@ SK-Logik: Nicht wirklich. C benötigt eine Laufzeitbibliothek wie C ++. Das ABI kann in C ++ über extern "C"so gesteuert werden, dass es von außen C-kompatibel ist. Daher haben Sie die internen Vorteile von C ++ (höhere
Typensicherheit
3
@ SK-logic Das nicht spezifizierte ABI ist einfach ein gelöstes Problem, siehe SWIG, Boost.Python und eine Vielzahl anderer Sprachbindungen.
Konrad Rudolph
3
@MSalters nicht über Ausnahmen und ihre allgemeine Nicht-Arbeit über Bibliotheksgrenzen hinweg
vergessen
3
-1 für C ++ Vorschlag. C ist einfach, C ++ macht es unnötig schwer.
Ernest Friedman-Hill
23

Es gibt so ziemlich zwei Möglichkeiten:

  • eine C-API. Praktisch jede Sprache, die jemals existiert hat, lädt eine C-Bibliothek und ruft deren Funktionen auf. Wie Sie dies tun, hängt von der Ausgangssprache ab.
  • eine Art RPC-Mechanismus. Dies kann eine REST-API sein, die über HTTP ausgeführt wird, oder eine Binärschnittstelle, die über einen Socket ausgeführt wird. Wenn Sie sich nicht für den kleinsten gemeinsamen Nennermechanismus entscheiden (z. B. einen Socket), laufen Sie Gefahr, keine Clientzugriffsroutinen zu haben (z. B. verfügen einige Sprachen nicht über die richtigen SOAP-Clients, um eine mit SOAP implementierte API aufzurufen, oder es gibt Interoperabilitätsprobleme). Halten Sie sich an die einfachste Methode, entweder eine HTTP / REST-Schnittstelle oder einen Socket. Sockets haben den Vorteil, dass sie keinen HTTP-Server benötigen, um die Schnittstelle für die Clients verfügbar zu machen, und einfacher auf demselben Server wie der Client mit einer besseren Leistung ausgeführt werden können.

Die dafür erforderliche Arbeit hängt vom verwendeten System ab, z. B. funktioniert eine Socket-Schnittstelle, clientseitige Bibliotheken sind jedoch im Vergleich zu http-Bibliotheken in der Regel niedriger.

Sie könnten versuchen, eine Netzwerkbibliothek zu finden, die alle Sprachen unterstützt, die Sie verwenden möchten, und die API in Bezug auf diese Bibliothek implementieren. Die Verwendung von ZeroMQ bietet Ihnen z Dann muss jede Sprache, die Ihre API aufrufen möchte, die ZeroMQ-Clientbibliothek verwenden, um dies zu tun. Wählen Sie eine Bibliothek, die eine breite Palette von Sprachen unterstützt und Ihnen die Möglichkeit bietet, sowohl prozessbegleitend als auch prozessunabhängig zu kommunizieren, um eine optimale Leistung zu erzielen.

gbjbaanb
quelle
Welche Schritte müsste ich also unternehmen, wenn ich die API auch in mehreren Sprachen schreiben möchte? (In meinem Fall wären dies Javascript, C ++ und Java.)
Anderson Green
Sollte ich nur 3 separate RESTful-APIs für jede der Sprachen schreiben?
Anderson Green
In jeder dieser Sprachen schreiben Sie einen nativen Wrapper, der das Laden und Aufrufen der zugrunde liegenden C-DLL übernimmt. Oder schreiben Sie es in C ++ und verwenden Sie SWIG, um dies für Sie zu tun. Wenn Sie eine REST-API verwenden, gilt dasselbe: Schreiben Sie entweder eine einzelne API und dann drei Wrapper. Wenn Sie jedoch eine REST-API schreiben, kann jede Sprache die REST-API direkt aufrufen mit einer Verpackung.
Gbjbaanb
Wäre die DLL (dynamisch verknüpfte Bibliothek) mit jeder Plattform außer Windows kompatibel? Ich benötige hier plattformübergreifende Kompatibilität.
Anderson Green
Nein, Sie müssen es für andere Plattformen neu kompilieren. Linux verwendet zum Beispiel .so anstelle von .dll. Es ist nur eine einfache Neukompilierung erforderlich, keine (oder nur geringfügige) Codeänderungen.
Gbjbaanb
12

Wenn die Leistung und die Anruflatenz kein Problem darstellen, sollten Sie eine umfassende Befehlszeilenschnittstelle bereitstellen (möglicherweise mithilfe einer Skriptsprache). ImageMagick kann ein gutes Beispiel für eine solche "API" sein. Ein weiteres gutes Beispiel ist das Tk-Toolkit.

SK-Logik
quelle
Welche Skriptsprache und / oder Programmiersprache würden Sie zum Erstellen einer fremden Befehlszeilen-Funktionsschnittstelle empfehlen? Haben Sie auch konkrete Beispiele für solche Schnittstellen gefunden?
Anderson Green
@AndersonGreen, jede Sprache mit anständiger Metaprogrammierung ist für einen solchen Zweck in Ordnung. ZB Schema, MetaLua, verschiedene andere einbettbare Lisps, Tcl. Sie können auch problemlos Ihre eigene Befehlssprache implementieren. Viele CAD / CAE-Systeme arbeiten auf diese Weise. Ein bereits erwähntes Tk ist ein weiteres typisches Beispiel.
SK-logic
Wenn Sie eine Befehlszeilenschnittstelle auf diese Weise verwenden möchten, würden Sie die Konsolenausgabe für einen bestimmten Befehl erhalten (z. B. whoamiunter Ubuntu, um den Benutzernamen abzurufen), oder hatten Sie etwas anderes im Sinn?
Anderson Green
@AndersonGreen, stdin und stdout sollten in den meisten Fällen ausreichen.
SK-logic
5

Was genau meinen Sie mit API?

Auf vielen Plattformen könnten Sie eine Verknüpfung zu einer DLL oder einer ähnlichen Konstruktion herstellen, müssten aber für ein bestimmtes natives Ziel (Intel / ARM) oder Endianness noch neu kompiliert werden? Eine bestimmte Binärschnittstelle kann aufgrund von Problemen mit Datentypen oder Konstrukten (Zeiger, die versucht werden, auf Sprachen zurückzukehren, die sie nicht gut unterstützen) weiterhin Probleme mit bestimmten Sprachen haben einige Sprachen auszuschließen oder ihren Gebrauch von diesen Sprachen umständlich zu machen.

So etwas wie C und eine Schnittstelle, die auf binären Endpunkten in einer DLL basiert, können auf den meisten Plattformen und in den meisten Sprachen problemlos aufgerufen werden, müssen jedoch möglicherweise anders kompiliert und / oder in verschiedenen Varianten angeboten oder mit verschiedenen statischen Bibliotheken verknüpft werden.

Es scheint mir, dass die Wahl der Sprache, in der Sie Ihre Bibliothek oder Ihren Service schreiben, oder was auch immer per Definition nicht für die Frage von Bedeutung ist, bis Sie mehr über die Plattform / den Service erfahren, den die API bereitstellt. Wenn Sie davon ausgehen können, dass ein Netzwerkstapel verfügbar ist und keine Leistung auf Funktionsebene mit direkter Verknüpfung erforderlich ist, kann die API leicht HTTP-basiert sein, wobei die Clientsprache eine Art Shim verwendet, um die Anforderungen transparent zu machen.

Ich denke, im Allgemeinen ist diese Frage zu weit gefasst, um in der realen Welt nützlich zu sein, da Sie nicht angegeben haben, welche Art von API angesichts der Art des angebotenen Dienstes geeignet sein könnte.

Cade Roux
quelle
2

Hinzufügen von Antworten, die die Verwendung eines RPC-Mechanismus vorschlagen. Sie können Apache Thrift verwenden ( http://thrift.apache.org/ ). Grundsätzlich handelt es sich um ein RPC-Framework.

Nach dem Thrift-Wiki:

Das Apache Thrift-Software-Framework für die Entwicklung skalierbarer, sprachübergreifender Dienste kombiniert einen Software-Stack mit einer Code-Generierungs-Engine, um Dienste zu erstellen, die effizient und nahtlos zwischen C ++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C # funktionieren. Cocoa, JavaScript, Node.js, Smalltalk, OCaml und Delphi und andere Sprachen

gt5050
quelle
Wie können fremde Funktionsaufrufe mit Apache Thrift durchgeführt werden?
Anderson Green
0

Lassen Sie eine beliebige Sprache eine Textdatei mit der Funktion zum Aufrufen und Weiterleiten von Parametern ausgeben. Lassen Sie Ihre App "Ich komme mit jedem zurecht" ein Verzeichnis überwachen und sobald sie eine process-call.txt sieht, kann sie funktionieren. Keine Server oder Netzwerkprotokolle; Selbst eine Methode, die keine Computersprache ist, kann die Funktionen auslösen. Sogar eine Person könnte einfach die Textdatei erstellen.

Der Inhalt könnte folgendermaßen aussehen:

Call-method:  fdisk()
Params:  (string) "/root", (string) "write-back-file-expected.txt"

;) Sie könnten jedoch ewig warten, bis Sie eine Antwort erhalten. Sie müssen nur ein paar Bytes in den anderen Prozess verschieben, aber ich bin sicher, dass das nicht die ganze Spezifikation ist.

Pareshkumar
quelle
Scheint zu kompliziert, wenn Sie nur eine Befehlszeilenschnittstelle + stdin / stdout haben könnten.
Setzen Sie Monica
1
Noch besser kann man das ++ 1 nennen, Brendan. Ich habe es nie in Aktion gesehen, aber es war einmal, als Leute Löcher in die Karte gestanzt haben, um die Bytes zu übertragen.
Pareshkumar
4
Das ist eine Scherzantwort, oder? Das machen wir hier nicht.
Ernest Friedman-Hill
Nun, der fdisk- und / oder root-Teil ist ein Scherz, aber ich war über 5 Jahre als Plattform-F & E (Entwickler und Analyst) beteiligt, um ein Plattform-Produkt zu entwickeln, das gut in den 10er Jahren Millionen von Dollar hervorbrachte. Mit dieser Art von REST-Methode werden Millionen von versendbaren physischen (nicht PDF- und E-Mail-) Elementen für den Client ausgespuckt (wobei Dateien mit einer Größe von Hunderten von MB pro Element verarbeitet werden). Wir hatten große System-Triologie-SAP-MS-Office-SPS-Treiber-PDF-Workflow, die alle miteinander in Verbindung standen und gut mit einfachen UTF-8-Textdateien und einem Zip-in-Zip-in-Zip-Dateien zusammenarbeiteten. und kein HTTP-BS-Overhead.
Pareshkumar
Dürfte ich eine Frage stellen? Warum hält niemand JSON für einen Scherz? Wie ist das, was ich empfehle, anders? Wir hätten / hätten vielleicht json verwendet, aber es gab es 2003 nicht. XML ist zu fett, aber damals war das der Geschmack des Monats nicht die praktischste und einfachste Seele.
Pareshkumar
0

OpenGL ist ein gutes Beispiel für das, was Sie beschreiben - es ist eine in C geschriebene API, die so entworfen wurde, dass es einfach ist, Bindungen für andere Sprachen zu schreiben

  1. C-Bibliotheken können aus den meisten Programmiersprachen aufgerufen werden (normalerweise als kompilierte Erweiterungen oder Dinge wie PyPys ctypesBibliothek usw.).

  2. Alle Funktionen verwenden einfache Datentypen als Argumente (Boolesche Werte, Ganzzahlen, Gleitkommazahlen, Konstanten, Arrays), da es für Funktionen, die Zeiger verwenden, schwierig sein kann, diese in einige Sprachen zu übersetzen

  3. Eigene numerische Datentypen, die Genauigkeit und Signiertheit angeben (wobei sich int floatetc unterscheiden kann)

Die resultierende API ist nicht unbedingt die am besten zu verwendende C-API, die Sie schreiben könnten, wenn Sie nur C-Benutzer als Ziel haben. Dies bedeutet jedoch, dass die Funktionen fast direkt einer anderen Sprache ausgesetzt werden können (z. B. listen die PyOpenGL- Dokumente die Unterschiede auf, von denen die meisten ziemlich gering sind).

Zusätzlich zu dieser ausführlichen API können Sie weitere "entwicklerfreundliche" Wrapper schreiben (Spiel-Frameworks und dergleichen).

dbr
quelle