Comment puis-je écrire un ensemble de fonctions pouvant être appelées depuis (presque) n'importe quel langage de programmation?

33

J'aimerais trouver un moyen d'écrire une API accessible depuis n'importe quel autre langage de programmation via des liaisons de langage (ou un autre framework). Est-il possible de faire cela? Si tel est le cas, quel langage de programmation conviendrait le mieux pour écrire une API "multilingue"? Mon objectif est de créer un ensemble unique de fonctions auxquelles je peux accéder à partir de n'importe quel langage de programmation avec lequel je travaille, afin de ne pas avoir à réécrire manuellement l'intégralité de l'API dans chaque langue.

Anderson Green
la source
4
Si vous voulez simplement pouvoir dire "nous soutenons TOUT" pour des raisons marketing, vous pouvez simplement écrire une DLL de bas niveau ou une bibliothèque partagée en C. Si vous voulez que quelqu'un, par exemple, Java, utilise votre mieux fournir une interface Java.
Mjfgates
1
Vous dites "(presque)", quelles langues exclurez-vous à cette fin? Ou quels sont les plus importants pour vous?
Funkybro
22
Service Web? Vous pouvez écrire certaines fonctions dans php, par exemple. Presque toutes les langues ont la possibilité d'interagir avec les pages Web, de fournir des arguments et de lire les résultats.
Pieter B
7
+1 parce que c'est une question intéressante - mais votre question serait améliorée en expliquant pourquoi vous voulez le faire. Quels sont vos objectifs?
TarkaDaal
@PieterB => répondre.
Konrad Rudolph

Réponses:

44

Vous avez quelques options:

  1. Créez une interface HTTP, presque tout peut parler HTTP, ce qui vous donnera beaucoup de langues.

  2. Créez quelque chose qui puisse être lié à un environnement linguistique, cela prendra beaucoup de temps, car vous devrez trouver un moyen de le connecter à de nombreuses langues différentes.

Zachary K
la source
Quel type d'interface HTTP avez-vous à l'esprit, en particulier?
Anderson Green
@AndersonGreen Cela ne devrait pas avoir d'importance (car toute langue pouvant ouvrir une socket réseau peut parler HTTP), mais REST est un pseudo-standard utile.
Rétablir Monica le
7
REST + JSON serait une solution raisonnable
David Hayes
Je conviens également que l'utilisation de HTTP pour communiquer permet à pratiquement toutes les langues d'interagir avec les fonctions de votre application.
Only Bolivian Here Le
30

Je pense que C ou C ++ conviendrait le mieux à vos besoins. Vous pouvez utiliser SWIG (Simplified Wrapper and Interface Generator) pour générer des liaisons de langage à partir de votre API C ou C ++.

SWIG est un outil de développement logiciel qui relie des programmes écrits en C et C ++ à une variété de langages de programmation de haut niveau. SWIG est utilisé avec différents types de langages cibles, y compris les langages de script courants tels que Perl, PHP, Python, Tcl et Ruby. La liste des langues supportéescomprend également des langages non scriptés tels que C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), langage D, Go, Java comprenant Android, Lua, Modula-3, OCAML, Octave et R. Egalement plusieurs schémas interprétés et compilés les implémentations (Guile, MzScheme / Racket, Poulet) sont supportées. SWIG est le plus souvent utilisé pour créer des environnements de programmation interprétés ou compilés de haut niveau, des interfaces utilisateur et comme outil de test et de prototypage de logiciels C / C ++. SWIG est généralement utilisé pour analyser les interfaces C / C ++ et générer le "code d'enchaînement" requis pour que les langages cibles ci-dessus appellent le code C / C ++. SWIG peut également exporter son arbre d’analyse syntaxique sous la forme d’expressions s et Lisp. SWIG est un logiciel libre et le code généré par SWIG est compatible avec les projets commerciaux et non commerciaux ...

LMC
la source
32
C ++ serait un choix affreux. Cela pose de nombreux problèmes: dépendance à une bibliothèque d’exécution, ABI non spécifiée (en particulier mangling), etc. La génération de liaisons à partir d’en-têtes C ++ est extrêmement délicate. SWIG est une chose assez limitée. Visualisez toute l’infrastructure trop compliquée autour, par exemple, des liaisons Python Qt.
SK-logic
14
@ SK-logic: Pas vraiment. C a besoin d’une bibliothèque d’exécution semblable à C ++. L’ABI peut être contrôlé en C ++ via extern "C"une compatibilité C à l’extérieur. Vous avez donc les avantages internes du C ++ (sécurité de type supérieure, bibliothèques) mais les avantages externes du C (norme ABI de facto)
MSalters
3
@ SK-logic L'ABI non spécifié est simplement un problème résolu, voir SWIG, Boost.Python et une foule d'autres liaisons de langage.
Konrad Rudolph
3
@MSalters ne pas oublier les exceptions et leur non-workiness général à travers les frontières bibliothèque
sehe
3
-1 pour la suggestion C ++. C est facile, C ++ rend les choses inutilement difficiles.
Ernest Friedman-Hill
23

Il y a à peu près 2 façons:

  • une API C. Pratiquement toutes les langues existantes chargeront une bibliothèque C et appelleront ses fonctions. Cela dépend de la langue source.
  • un mécanisme RPC de quelque sorte. Cela peut être une API REST exécutée sur HTTP ou une interface binaire exécutée sur un socket. Sauf si vous optez pour le mécanisme du plus petit dénominateur commun (par exemple, un socket), vous courez le risque de ne pas avoir de routines d'accès client (par exemple, certaines langues ne disposent pas des clients SOAP appropriés pour appeler une API implémentée à l'aide de SOAP, ou en cas de problèmes d'interopérabilité). S'en tenir à la plus simple, soit une interface HTTP / REST, ou un socket. Les sockets ont l'avantage de ne pas nécessiter de serveur HTTP pour exposer l'interface aux clients et peuvent plus facilement s'exécuter sur le même serveur que le client offrant de meilleures performances.

Le travail requis pour cette tâche change en fonction du système utilisé. Par exemple, une interface de socket fonctionnera, mais les bibliothèques côté client ont tendance à être plus simples que les bibliothèques http.

Vous pouvez essayer de trouver une bibliothèque réseau prenant en charge toutes les langues que vous souhaitez utiliser et implémenter l'API en fonction de cette bibliothèque. Par exemple, utiliser ZeroMQ vous donne beaucoup de flexibilité pour écrire votre API à l'aide d'interfaces ZeroMQ. toute langue souhaitant appeler votre API doit alors utiliser la bibliothèque cliente ZeroMQ. Choisissez une bibliothèque prenant en charge un large éventail de langues et permettant une communication in-process ou out-of-process pour des performances optimales.

gbjbaanb
la source
Quelles mesures devrais-je prendre si je voulais également écrire l'API dans plusieurs langues? (Dans mon cas, ces langages seraient Javascript, C ++ et Java.)
Anderson Green
Devrais-je simplement écrire 3 API RESTful distinctes pour chacune des langues?
Anderson Green
Vous écrivez un wrapper natif dans chacune de ces langues qui gère le chargement et appelle la dll sous-jacente. Ou écrivez-le en C ++ et utilisez SWIG pour le faire à votre place. Si vous utilisez une API REST, la même chose s'applique: écrivez une seule API, puis 3 wrappers, mais si vous écrivez une API REST, chaque langue pourra appeler directement l'API REST. Ne vous inquiétez pas. avec une cape.
gbjbaanb
La DLL (bibliothèque liée dynamiquement) serait-elle compatible avec une plateforme autre que Windows? J'ai besoin de compatibilité entre plates-formes ici.
Anderson Green
non, vous devez le recompiler pour d'autres plates-formes. Linux, par exemple, utilise .so au lieu de .dll. Une recompilation directe est nécessaire, aucun changement de code (ou très mineur).
gbjbaanb
12

Si les performances et la latence des appels ne sont pas un problème, envisagez de fournir une interface de ligne de commande complète (probablement, en utilisant un langage de script par-dessus). ImageMagick peut être un bon exemple d'une telle "API". Un autre bon exemple est la boîte à outils Tk.

SK-logic
la source
Quel langage de script et / ou langage de programmation recommanderiez-vous dans le but de créer une interface de fonction étrangère en ligne de commande? Aussi, avez-vous trouvé des exemples concrets de telles interfaces?
Anderson Green
@AndersonGreen, toute langue avec une métaprogrammation décente est acceptable à cette fin. Scheme, MetaLua, divers autres Lisps incorporables, Tcl. Vous pouvez également facilement implémenter votre propre langage de commande. De nombreux systèmes de CAO / IAO fonctionnent de cette manière. Un Tk déjà mentionné est un autre exemple typique.
SK-logic
Pour utiliser une interface de ligne de commande de cette manière, obtiendriez-vous la sortie de la console pour une commande spécifique (telle que whoamiUbuntu pour obtenir le nom d'utilisateur), ou aviez-vous autre chose en tête?
Anderson Green
@AndersonGreen, piping stdin et stdout devraient suffire dans la plupart des cas.
SK-logic
5

Par API, que voulez-vous dire exactement?

Sur de nombreuses plates-formes, vous pouvez créer un lien vers une DLL ou une construction similaire, mais le fait de devoir être recompilé pour une cible native particulière (Intel / ARM) ou pour l’endianisme est-il toujours admissible? Une interface binaire particulière peut toujours rencontrer des difficultés avec certaines langues en raison de problèmes de types de données ou de constructions (les pointeurs essayant d’être renvoyés vers des langues qui ne les prennent pas bien en charge). Vous devrez donc également prendre en compte la conception de l’API afin de ne pas la modifier. exclure certaines langues ou rendre son utilisation lourde de ces langues.

Quelque chose de portable, comme C, et une interface basée sur des points de terminaison binaires dans une DLL peuvent être généralement appelés et appelables sur la plupart des plateformes et de la plupart des langues, mais il peut être nécessaire de les compiler différemment et / ou de les proposer sous différentes formes ou de les lier à différentes bibliothèques statiques.

Il me semble que le choix de la langue dans laquelle vous écrivez votre bibliothèque ou votre service ou quoi que ce soit est, par définition, indissociable de la question jusqu'à ce que vous en donniez davantage sur la plate-forme / service exposée par l'API. Si vous pouvez supposer qu'une pile réseau est disponible et que les performances au niveau des fonctions liées directement ne sont pas une exigence, l'API peut facilement être basée sur HTTP avec une sorte de shim pour la langue du client afin de rendre les requêtes transparentes.

Je pense que, d’une manière générale, cette question est trop vaste pour être utile dans le monde réel, car vous n’avez pas indiqué quel type d’API pourrait convenir compte tenu du type de service offert.

Cade Roux
la source
2

Pour ajouter aux réponses ci-dessus qui suggèrent l'utilisation d'un mécanisme RPC. Vous pouvez utiliser Apache Thrift. ( Http://thrift.apache.org/ ). C'est fondamentalement un framework RPC.

Selon le wiki Thrift:

Le framework logiciel Apache Thrift, destiné au développement de services inter-langues évolutifs, associe une pile logicielle à un moteur de génération de code pour créer des services efficaces et transparents entre C ++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C #, Cocoa, JavaScript, Node.js, Smalltalk, OCaml et Delphi et d'autres langages

gt5050
la source
Comment faire des appels de fonction à l'étranger avec Apache Thrift?
Anderson Green
0

Demandez à n'importe quelle langue d'écrire un fichier texte avec une fonction à appeler avec des paramètres à transmettre. Demandez à votre application "Je m'entends avec tout le monde" de regarder un répertoire et une fois qu'elle verra un processus-call.txt le faire fonctionner. Aucun serveur ou protocole réseau; même une méthode en langage non informatique peut initier les fonctions. Même une personne pourrait simplement créer le fichier texte.

Le contenu pourrait ressembler à:

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

;) vous pourriez attendre une éternité avant d’obtenir une réponse. Vous avez juste besoin d'insérer quelques octets dans l'autre processus, mais je suis sûr que ce n'est pas tout.

Pareshkumar
la source
Cela semble trop compliqué de ne disposer que d’une interface de ligne de commande + stdin / stdout.
Réintégrer Monica le
1
Encore mieux, appelez ++ 1 ça, Brendan. Je ne l'ai jamais vu en action, mais il était une fois des gens qui perforaient une carte pour transférer les octets.
Pareshkumar
4
Ceci est une réponse blague, non? Nous ne faisons pas ça ici.
Ernest Friedman-Hill
Bien que fdisk et / root soient une blague, mais j’ai été impliqué en tant que plate-forme de recherche et développement (développeur et analyste) pendant plus de 5 ans pour créer un produit de plate-forme qui a généré des gains de l'ordre de 10 millions de dollars. Il crache des millions d’articles physiques (pas de pdf et d’e-mails) pouvant être expédiés pour le client (avec des fichiers de traitement allant en centaines de Mo par article) en utilisant ce type de méthode REST. Nous avions d'importants flux de travail système triolgy-SAP-MS Office-Drivewrs-PDF qui fonctionnaient entre eux et fonctionnaient bien avec de simples fichiers au format UTF-8-text et un zip avec un zip avec un zip, et pas de surcharge HTTP bs.
Pareshkumar
Puis-je demander une question? Pourquoi personne ne pense que JSON est une blague? En quoi ce que je recommande est-il différent? Nous aurions / aurions peut-être utilisé json mais ce n’était pas autour de 2003. XML est trop gros, mais c’était la saveur du mois qui n’était pas la plus simple et la plus pratique.
Pareshkumar
0

OpenGL est un bon exemple de ce que vous décrivez - c'est une API écrite en C, conçue de manière à ce qu'il soit facile d'écrire des liaisons dans d'autres langues.

  1. Les bibliothèques C peuvent être appelées à partir de la plupart des langages de programmation (généralement en tant qu’extensions compilées, ou des choses comme la ctypesbibliothèque de PyPy, etc.)

  2. Toutes les fonctions prennent comme arguments des types de données simples (booléen, entier, virgule flottante, constantes, tableaux), car les fonctions utilisant des pointeurs peuvent être difficiles à traduire en certaines langues.

  3. Avoir ses propres types de données numériques, qui spécifient la précision et la signature (alors que int floatetc peut différer)

L'API résultante n'est pas nécessairement l'API C la plus conviviale que vous puissiez écrire si vous ne ciblez que des utilisateurs C. Cependant, cela signifie que les fonctions peuvent être presque directement exposées à une autre langue (par exemple, la documentation de PyOpenGL répertorie les différences, dont la plupart sont plutôt minimes).

En plus de cette API prolixe, vous pouvez écrire plus de wrappers "conviviaux pour les développeurs" autour de cela (frameworks de jeu et autres).

dbr
la source