¿Cómo puedo escribir un conjunto de funciones que se pueden invocar desde (casi) cualquier lenguaje de programación?

33

Me gustaría encontrar una manera de escribir una API a la que se pueda acceder desde cualquier otro lenguaje de programación a través de enlaces de idioma (o algún otro marco). ¿Es posible hacer esto? Si es así, ¿qué lenguaje de programación sería el más adecuado para escribir una API "cross-language"? Mi objetivo es crear un conjunto único de funciones a las que pueda acceder desde cualquier lenguaje de programación con el que estoy trabajando, para que no necesite volver a escribir manualmente la API completa en cada idioma.

Anderson Green
fuente
44
Si solo quiere poder decir "apoyamos TODO" por razones de marketing, puede escribir un archivo DLL de bajo nivel o una biblioteca compartida en C. Si quiere que alguien en Java, digamos, use su cosa, Mejor proporcionar una interfaz Java.
mjfgates
1
Usted dice "(casi) cualquiera", ¿qué idiomas excluiría para este propósito? ¿O cuáles son los más importantes para ti?
funkybro
22
¿Servicio web? Puede escribir algunas funciones en, por ejemplo, php. Casi cualquier idioma tiene la posibilidad de interactuar con páginas web, proporcionar argumentos y leer los resultados.
Pieter B
77
+1 porque es una pregunta interesante, pero su pregunta se mejoraría diciendo por qué quiere hacer esto. ¿Cuáles son tus metas?
TarkaDaal
@PieterB => respuesta.
Konrad Rudolph

Respuestas:

44

Tienes pocas opciones:

  1. Cree una interfaz HTTP, casi todo puede hablar HTTP, por lo que obtendrá muchos idiomas.

  2. Cree algo que pueda vincularse a un tiempo de ejecución de idioma, esto llevará bastante tiempo ya que necesitará encontrar una manera de conectarlo a muchos idiomas diferentes.

Zachary K
fuente
¿Qué tipo de interfaz HTTP tienes en mente, específicamente?
Anderson Green
@AndersonGreen No debería importar (ya que cualquier lenguaje que pueda abrir un socket de red puede hablar HTTP), pero REST es un pseudo-estándar útil.
Vuelva a instalar Mónica
77
REST + JSON sería una solución razonable
David Hayes
También estoy de acuerdo, el uso de HTTP para comunicarse permite que casi todos los idiomas interactúen con las funciones de su aplicación.
Solo boliviano aquí
30

Creo que C o C ++ serían los más adecuados para su propósito. Puede usar SWIG (generador de interfaz y envoltorio simplificado) para generar enlaces de lenguaje desde su API C o C ++.

SWIG es una herramienta de desarrollo de software que conecta programas escritos en C y C ++ con una variedad de lenguajes de programación de alto nivel. SWIG se utiliza con diferentes tipos de lenguajes de destino, incluidos los lenguajes de secuencias de comandos comunes, como Perl, PHP, Python, Tcl y Ruby. La lista de idiomas admitidos.también incluye lenguajes sin secuencias de comandos como C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), D, lenguaje Go, Java, incluidos Android, Lua, Modula-3, OCAML, Octave y R. También varios esquemas interpretados y compilados implementaciones (Guile, MzScheme / Racket, Chicken) son compatibles. SWIG se usa más comúnmente para crear entornos de programación interpretados o compilados de alto nivel, interfaces de usuario y como herramienta para probar y crear prototipos de software C / C ++. SWIG se usa típicamente para analizar interfaces C / C ++ y generar el 'código de pegamento' requerido para que los lenguajes de destino anteriores llamen al código C / C ++. SWIG también puede exportar su árbol de análisis en forma de expresiones XML y Lisp. SWIG es software libre y el código que genera SWIG es compatible con proyectos comerciales y no comerciales ...

LMC
fuente
32
C ++ sería una elección horrible. Existen numerosos problemas con él: la dependencia de una biblioteca en tiempo de ejecución, ABI no especificado (especialmente la manipulación), etc. Generar enlaces a partir de encabezados de C ++ es prohibitivamente complicado. SWIG es una cosa bastante limitada. Vea toda la infraestructura complicada en torno a, por ejemplo, los enlaces Python Qt.
SK-logic
14
@ SK-logic: en realidad no. C necesita una biblioteca en tiempo de ejecución al igual que C ++. El ABI se puede controlar en C ++ por extern "C"lo que es compatible con C en el exterior. Por lo tanto, tiene las ventajas internas de C ++ (mayor seguridad de tipos, bibliotecas) pero las ventajas externas de C (estándar de facto ABI)
MSalters
3
@ SK-logic El ABI no especificado es simplemente un problema resuelto, vea SWIG, Boost.Python y una gran cantidad de enlaces de otros idiomas.
Konrad Rudolph
3
@MSalters no se olvide de las excepciones y su no workiness general a través de los límites de la biblioteca
sehe
3
-1 para sugerencia de C ++. C es fácil, C ++ hace las cosas innecesariamente difíciles.
Ernest Friedman-Hill
23

Hay casi 2 formas:

  • una API de C. Prácticamente cualquier lenguaje que haya existido cargará una biblioteca C y llamará a sus funciones. Cómo hacerlo depende del idioma de origen.
  • un mecanismo RPC de algún tipo. Esto puede ser una API REST que se ejecuta sobre HTTP, o una interfaz binaria que se ejecuta sobre un socket. A menos que elija el mecanismo de mínimo común denominador (por ejemplo, un socket), corre el riesgo de no tener rutinas de acceso de clientes (por ejemplo, algunos idiomas no tienen los clientes SOAP adecuados para llamar a una API implementada usando SOAP, o existen problemas de interoperabilidad). Apéguese a lo más simple, ya sea una interfaz HTTP / REST o un socket. Los sockets tienen la ventaja de que no necesitan un servidor HTTP para exponer la interfaz a los clientes, y pueden ejecutarse más fácilmente en el mismo servidor que el cliente con un mejor rendimiento.

El trabajo requerido para estos cambios depende del sistema utilizado, por ejemplo, una interfaz de socket funcionará, pero las bibliotecas del lado del cliente tienden a tener un nivel más bajo en comparación con las bibliotecas http.

Podría intentar encontrar una biblioteca de red que admita todos los idiomas que desea usar e implementar la API en términos de esa biblioteca; por ejemplo, usar ZeroMQ le brinda mucha flexibilidad, por lo que escribiría su API usando interfaces ZeroMQ, y entonces cualquier idioma que quiera llamar a su API debe usar la biblioteca del cliente ZeroMQ para hacerlo. Elija una biblioteca que admita una amplia gama de idiomas y le permita la comunicación tanto en proceso como fuera de proceso para obtener el mejor rendimiento.

gbjbaanb
fuente
Entonces, ¿qué pasos debería seguir si quisiera escribir la API también en varios idiomas? (En mi caso, esos lenguajes serían Javascript, C ++ y Java.)
Anderson Green
¿Debo escribir 3 API RESTful separadas para cada uno de los idiomas?
Anderson Green
Usted escribe un contenedor nativo en cada uno de estos idiomas que maneja la carga y la llamada al dll subyacente. O escríbalo en C ++ y use SWIG para hacer esto por usted. Si está utilizando una API REST, entonces se aplica lo mismo, ya sea escribir una sola API y luego 3 envoltorios, pero si está escribiendo una API REST, entonces cada idioma podrá llamar a la API REST directamente, no se moleste con una envoltura
gbjbaanb
¿La dll (biblioteca vinculada dinámicamente) sería compatible con cualquier plataforma además de Windows? Necesito compatibilidad multiplataforma aquí.
Anderson Green
no, deberías recompilarlo para otras plataformas. Linux, por ejemplo, usa .so en lugar de .dll. Solo se necesita una recompilación directa, sin cambios de código (o muy pequeños).
gbjbaanb
12

Si el rendimiento y la latencia de las llamadas no son un problema, considere proporcionar una interfaz de línea de comandos completa (probablemente, utilizando un lenguaje de script encima). ImageMagick puede ser un buen ejemplo de tal "API". Otro buen ejemplo es el kit de herramientas Tk.

SK-logic
fuente
¿Qué lenguaje de programación y / o lenguaje de programación recomendaría para crear una interfaz de función externa de línea de comando? Además, ¿ha encontrado ejemplos concretos de tales interfaces?
Anderson Green
@AndersonGreen, cualquier lenguaje con metaprogramación decente está bien para tal fin. Por ejemplo, Scheme, MetaLua, varios otros Lisps integrables, Tcl. También puede implementar fácilmente su propio lenguaje de comandos. Muchos sistemas CAD / CAE funcionan de esta manera. Un Tk ya mencionado es otro ejemplo típico.
SK-logic
Para utilizar una interfaz de línea de comandos de esta manera, ¿obtendría la salida de la consola para un comando específico (como whoamien Ubuntu para obtener el nombre de usuario), o tenía algo más en mente?
Anderson Green
@AndersonGreen, la tubería stdin y stdout deberían ser suficientes en la mayoría de los casos.
SK-logic
5

Por API, ¿qué quieres decir exactamente?

En muchas plataformas, puede vincular a una DLL o construcción similar, pero ¿tendría que volver a compilarse para un objetivo nativo particular (Intel / ARM) o la endianness aún califica? Una interfaz binaria en particular aún puede tener dificultades con ciertos idiomas debido a problemas de tipo de datos o construcciones (punteros que intentan regresar a idiomas que no los admiten bien), por lo que también debería considerar el diseño de la API en sí misma para no para excluir algunos idiomas o hacer que su uso sea engorroso.

Algo portátil como C y una interfaz basada en puntos finales binarios en una DLL puede estar bien y, en general, se puede llamar en la mayoría de las plataformas y desde la mayoría de los lenguajes, pero es posible que deba compilarse de manera diferente y / u ofrecerse en diferentes versiones o vincularse a diferentes bibliotecas estáticas.

Me parece que la elección del idioma en el que escribe su biblioteca o servicio o lo que sea, por definición, no es intrínseco a la pregunta hasta que haya dado más información sobre la plataforma / servicio que expone la API. Si puede suponer que hay una pila de red disponible y el rendimiento de nivel de llamada de función con enlace directo no es un requisito, la API podría estar fácilmente basada en HTTP con algún tipo de calce para que el idioma del cliente haga transparentes las solicitudes.

Creo que, en general, esta pregunta es demasiado amplia para ser útil en el mundo real, porque no ha dado indicaciones sobre qué tipo de API podría ser adecuada dado el tipo de servicio que se ofrece.

Cade Roux
fuente
2

Para agregar a las respuestas anteriores que sugieren utilizar un mecanismo RPC. Puede usar Apache Thrift. ( Http://thrift.apache.org/ ). Básicamente es un marco RPC.

Según la wiki de Thrift:

El marco de software Apache Thrift, para el desarrollo escalable de servicios en varios idiomas, combina una pila de software con un motor de generación de código para crear servicios que funcionan de manera eficiente y sin problemas entre C ++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C #, Cacao, JavaScript, Node.js, Smalltalk, OCaml y Delphi y otros idiomas

gt5050
fuente
¿Cómo se pueden hacer llamadas a funciones externas usando Apache Thrift?
Anderson Green
0

Haga que cualquier idioma escriba un archivo de texto con función para llamar con parámetros para pasar. Haga que su aplicación "Me llevo bien con cualquiera" vea un directorio y una vez que vea un proceso call.txt haga que funcione. No hay servidores o protocolos de red; incluso un método de lenguaje no informático puede iniciar las funciones. Incluso una persona podría simplemente crear el archivo de texto.

El contenido podría verse así:

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

;) sin embargo, puede esperar para siempre para obtener una respuesta. Solo necesita insertar algunos bytes en el otro proceso, pero estoy seguro de que esa no es la especificación completa.

Pareshkumar
fuente
Parece demasiado complicado cuando solo podría tener una interfaz de línea de comandos + stdin / stdout.
Vuelva a instalar Mónica
1
Incluso mejor llamada puede ++ 1 que, Brendan. Nunca lo vi en acción, pero una vez la gente estaba haciendo agujeros en la tarjeta para transferir los bytes.
Pareshkumar
44
Esta es una respuesta de broma, ¿verdad? No hacemos eso aquí.
Ernest Friedman-Hill
Bueno, la parte fdisk y / root es una broma, pero estuve involucrado como plataforma de I + D (desarrollador y analista) durante más de 5 años para crear un producto de plataforma que produjo buenos en los 10 de millones de dólares. Escupió millones de elementos físicos enviables (no PDF y correos electrónicos) para el cliente (con archivos de procesamiento que varían en cientos de MB por elemento) utilizando este tipo de método REST. Tuvimos un gran flujo de trabajo del sistema Triolgy-SAP-MS Office-PLC Drivewrs-PDF, todo el uno al otro y funciona bien junto con archivos de texto UTF-8 simples y un zip con un zip con un zip, y sin sobrecarga de HTTP bs.
Pareshkumar
¿Puedo hacer una pregunta? ¿Por qué nadie piensa que JSON es una broma? ¿Cómo es lo que recomendé diferente? Hubiéramos / podríamos haber usado json pero no existía en 2003. XML es demasiado gordo, pero en ese entonces ese era el sabor del mes, no la más práctica y simple de las almas.
Pareshkumar
0

OpenGL es un buen ejemplo de lo que describe: es una API escrita en C, diseñada de una manera que es fácil de escribir enlaces en otros idiomas

  1. Las bibliotecas C se pueden llamar desde la mayoría de los lenguajes de programación (generalmente como extensiones compiladas o cosas como la ctypesbiblioteca de PyPy, etc.)

  2. Todas las funciones toman tipos de datos simples como argumentos (booleano, entero, coma flotante, constantes, matrices), ya que las funciones que toman punteros pueden ser difíciles de traducir a algunos idiomas.

  3. Tener sus propios tipos de datos numéricos, que especifican precisión y firma (mientras que int floatetc. pueden diferir)

La API resultante no es necesariamente la API de C más agradable de usar que podría escribir si se dirige solo a usuarios de C. Sin embargo, significa que las funciones pueden exponerse casi directamente a otro idioma (por ejemplo, los documentos de PyOpenGL enumeran las diferencias, la mayoría de las cuales son bastante mínimas)

Además de esta API detallada, puede escribir más envoltorios "amigables para el desarrollador" alrededor de esto (marcos de juego y demás)

dbr
fuente