📜 ⬆️ ⬇️

We build the Python interpreter into a java application using the Panama project

A couple of days ago I saw Brian Goetz's tweet, but only today my hands reached around to play with examples.

image

About this and I want to briefly tell.

About the Panama project on Habré already wrote , therefore I will just show couple of simple examples of how it is possible to apply native binder .

First of all, you will need a C compiler. If you are using Linux or MacOS, then you already have it. If Windows, you have to first install Build Tools for Visual Studio 2017 . And, of course, you need OpenJDK with Panama support. You can get it either by assembling the “foreign” branch of the corresponding repository , or by downloading an Early-Access build .

Let's start with a minimal example - a simple function that adds two numbers:

adder.h

#ifndef _ADDER_H #define _ADDER_H __declspec(dllexport) int add(int, int); #endif 

adder.c

 #include "adder.h" __declspec(dllexport) int add(int a, int b) { return a + b; } 

Example.java

 // импорт jextract'нутых "заголовочных" классов import static com.example.adder_h.*; public class Example { public static void main(String[] args) { System.out.println(add(3, 5)); } } 

We compile in DLL

 cl /LD adder.c 

We use the jextract utility to generate a java interface based on the header file:

 jextract -L . -l adder -o adder.jar -t "com.example" adder.h 

And we use the resulting jar file to build and run java code:

 javac -cp adder.jar Example.java java -cp .;adder.jar Example 

While not particularly impressive, but allows you to understand the principle. Now try using python37.dll.

PythonMain.java

 import java.foreign.Libraries; import java.foreign.Scope; import java.foreign.memory.Pointer; import static org.python.Python_h.*; import static org.python.pylifecycle_h.*; import static org.python.pythonrun_h.*; public class PythonMain { public static void main(String[] args) { Py_Initialize(); try (Scope s = Scope.newNativeScope()) { PyRun_SimpleStringFlags(s.allocateCString( "print(sum([33, 55, 66]))\n"), Pointer.nullPointer()); } Py_Finalize(); } } 

We generate interfaces:

 jextract -L "C:\Python37" -l python37 -o python.jar -t "org.python" --record-library-path C:\Python37\include\Python.h 

Compile and run:

 javac -cp python.jar PythonMain.java java -cp .;python.jar PythonMain 

Congratulations, your java-application has just loaded the Python interpreter into itself and executed the script in it!

image

More examples can be found in the instructions for pioneers .

Source: https://habr.com/ru/post/440470/