La programación multilenguaje, como su nombre indica, implica el uso de más de un lenguaje de programación en un solo programa. Hay una gran cantidad de lenguajes de programación y es una experiencia común que deseamos poder usar componentes de otros lenguajes también. Bueno, a primera vista, puede parecer extraño usar más de un idioma, compilar códigos en más de un idioma, pero al final del día, es muy útil.
Antes de profundizar en los detalles y las cosas basadas en código, retrocedamos un poco en la historia de los lenguajes de programación: la historia de Java y la historia de los sistemas operativos. Fue en la década de 1940 cuando surgieron los lenguajes de programación de nivel ensamblador. 1951: entró en vigor el lenguaje de la Asamblea Regional. 1958 – ALGOL; 1959 – COBOL (Common Business Oriented Language) y finalmente BASIC (Código de instrucciones simbólicas para principiantes) en 1964. Finalmente, obtuvimos C en 1972. Python llegó en 1990, pero solo se volvió popular en los días actuales debido a la llegada de Técnicas de Data Science y Machine Learning. Java nació en 1995. Otros lenguajes como Go, Rust, Dark, Kotlin, Swift, Scala, Scratch, etc. son desarrollos muy recientes. Ahora, ¿por qué dije todo esto? Puede parecer irrelevante para el tema de discusión, pero en realidad no lo es.
Es aceptable que diferentes lenguajes de programación tengan diferentes capacidades. Por ejemplo, C y C++ admiten punteros; Python es bueno para la ciencia de datos y los campos basados en IA; R es bueno para análisis de datos y operaciones matemáticas. Hablando desde mi experiencia personal, BASIC fue el primer lenguaje que usé, como en 2011. (Usé QBASIC principalmente). Aunque QBASIC es un lenguaje interpretado, luego cambié a QB64, que es una versión modernizada de BASIC y en su mayoría compila y genera un archivo EXE. Aparte de estos, hay veces que también hemos usado scripts ejecutables por máquina para lograr ciertos objetivos. Por ejemplo, un script bash para alternar el Bluetooth de su computadora, un archivo bat para comunicarse con un periférico conectado y muchos más.
Ahora, puede haber momentos en los que estés como, “¡Dios mío! Desearía que esta característica del idioma X también estuviera presente en el idioma Y”. Muchas veces todos lo hemos enfrentado. Pero ahora, con la ayuda de la clase Process, JNI e IO en Java, podemos acceder a las funciones de cualquier lenguaje de programación en Java, siempre que ya esté instalado en la máquina, junto con las dependencias. Por ejemplo, podemos usar las bibliotecas Python OpenCV o Python text to speech (PyTTSx3) de java.
Implementación:
Un programa corto para ejecutar un motor de texto a voz desde Java. Consta de dos archivos, a saber, tt.py de python y GFG.java de java.
Archivo 1: tts.py
Python3
# Python Demo Program # System for reading command line arguments import sys # Our Text to speech module import pyttsx3 if __name__ == "__main__": engine = pyttsx3.init() # Command line inputs saved in arg for arg in sys.argv[1:]: # Speaking the input engine.say(arg) engine.runAndWait()
Archivo 2: GFG.java
Java
// Java Program to Run a Text to Speech Engine // Importing I/O classes import java.io.*; // Main class class GFG { // Main driver method public static void main(String args[]) { // Custom input string consisting of text to speak String str= "Hello world"; // Try block to handle the exceptions try { Process ec=Runtime.getRuntime().exec("python tts.py "+str); //Using str as command line argument for the python script ec.waitFor(); //Waiting for the python script to finish executing } catch(Exception excep) { excep.printStackTrace(); } } }
Producción:
Hello world (spoken)
Bien, ahora siguiendo las definiciones,
“Los métodos ProcessBuilder.start() y Runtime.exec crean un proceso nativo y devuelven una instancia de una subclase de Proceso que se puede usar para controlar el proceso y obtener información sobre él”.
– Documentaciones
Implementación:
Se ve que podemos transferir el flujo de control de la aplicación Java a la secuencia de comandos de Python y, una vez completada la ejecución de la secuencia de comandos, se devuelve el flujo de control. Ahora, la pregunta es cómo transferir datos también, además del flujo de control solamente. Aquí entran en juego las clases I/O.
Desde el programa python, podemos imprimir los datos que queremos en STDOUT. (Usando la función simple print() en python). Ahora, la instancia ec de la clase Process tiene una función llamada getInputStream() . Esto devuelve un objeto InputStream para el programa Java. Ahora, las entradas del flujo de entrada se pueden manejar fácilmente con las clases BufferedReader o Scanner. El STDOUT de la clase Python está conectado al flujo de entrada de la instancia de la clase Process.
Ejemplo 1: Archivo: tts.py
Python3
# Importing required python classes import sys import pyttsx3 if __name__ == "__main__": engine = pyttsx3.init() # Iterating over using for loop for arg in sys.argv[1:] engine.say(arg) engine.runAndWait() # Print to STDOUT of python script print("Execution from Python completed")
Ejemplo 2: Archivo GFG.java
Java
// Importing java I/O classes import java.io.*; // Main class class GFG { // MAin driver method public static void main(String args[]) { // Custom input string String str = "Hello world"; // Try block to check for exceptions try { // Creating object of Processor class for python // script Process ec = Runtime.getRuntime().exec( "python tts.py " + str); // Taking input from user by // creating object of BufferedReader class // as for less salalbilty it is fast // Connect STDOUT of Python script to // BufferedReader of Java BufferedReader br = new BufferedReader( new InputStreamReader(ec.getInputStream())); // Initially declaring and initializing empty // string String st = " "; // Read all outputs from python script while ((st = br.readLine()) != null) { // Printing them System.out.println(st); } ec.waitFor(); } // Catch block to handle the exceptions catch (Exception excep) { // Print the exception/s along twith line number // using pprintStacktrace() method excep.printStackTrace(); } } }
Producción:
Hello world (Spoken) Execution from Python completed
Explicación de salida:
El resultado cuando se ejecuta el programa Java es ‘Hello World’ en formato de audio y ‘Ejecución desde Python completada’ en STDOUT. Ahora, también podemos querer ejecutar algunos comandos de shell desde el programa Java para interactuar con el sistema.
Ejemplo 3: Archivo GFG.java
Java
// Java Program to Shut-Down the Computer // Importing input output classes import java.io.*; // Main class class GFG { // Main driver method public static void main(String args[]) { // Try block to check for exceptions try { // Windows machine shutdown Process ec = Runtime.getRuntime().exec( "shutdown -s -f -t 0"); ec.waitFor(); // LINUX machine shutdown ec = Runtime.getRuntime().exec("sudo poweroff"); ec.waitFor(); } // catch block to handle exceptions catch (Exception excep) { // Print and display the exception on the console // using printStackTrace() method excep.printStackTrace(); } } }
Ahora, como dice el encabezado, ¿qué es JNI? JNI o Java Native Interface proporciona una interfaz (un archivo de encabezado .h) para que podamos incluirla en nuestros programas C y C++ y llamar a las funciones en el programa C desde nuestro programa Java. Las funciones en el programa C se denominan funciones nativas, y de ahí el nombre. Sin embargo, profundizando un poco en el JNI, podemos definir los métodos nativos en java como se ve en la siguiente ilustración como se muestra a continuación.
Ilustración:
native void function(parameters) { ... }
La palabra clave native aquí significa que se debe acceder a este método en particular desde un código nativo externo definido en C o C++. Por otro lado, para compilar un programa java con métodos nativos. Necesitamos usar javah para JDK más antiguos o javac -h para los JDK más recientes. Esto genera un archivo de encabezado .h que debe incluirse en el programa C con el preprocesador #include. La mayoría de nosotros usamos el compilador gcc, y se puede usar para compilar el programa C en una biblioteca .dll .
static { System.loadLibrary("library.dll"); }
Si el programa C se compila en el archivo library.dll, el mismo se puede importar al programa java de esta manera. Las funciones definidas en el programa C al incluir el encabezado .h generado por javac -h pueden llamarse directamente funciones nativas.
Como hemos visto, la clase Process se puede usar para llamar a programas escritos en otros lenguajes, así como scripts de shell. Es bastante imperativo decir que la clase Process también se puede usar para interactuar con el hardware conectado como lo hace la máquina cuando no hay una biblioteca adecuada en Java para el mismo. Aquí, estamos hablando principalmente de dispositivos de comunicación en serie.
La clase Process y el uso de múltiples lenguajes de programación en un solo proyecto pueden ser un salvavidas cuando el tiempo es muy poco y las bibliotecas apropiadas no están disponibles en un solo idioma. Por ejemplo, no somos muy fluidos en Python. Somos más un programador de Java. Por lo tanto, principalmente escribimos programas en Java, pero hay algunos casos en los que Python tiene mejores bibliotecas. Podemos usar fácilmente la clase Process para invocarlos.
Nota: tenga en cuenta bibliotecas como Jython que podrían ejecutar secuencias de comandos de Python desde Java directamente, pero no estamos hablando únicamente de python. La clase de proceso puede ejecutar programas de todos y cada uno de los lenguajes de programación, siempre que sea compatible con su máquina, y no necesita aprender otras bibliotecas para lograr lo mismo. Sería de gran ayuda en los proyectos. Como si quisiera analizar una gran cantidad de datos que obtiene en su programa escrito en Java. Uno puede simplemente pasar los datos a un programa en R o en Python para analizar los datos en lugar de hacer lo mismo manualmente en Java.
Publicación traducida automáticamente
Artículo escrito por adityamitra5102 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA