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. 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 .

    image





    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) intadd(int, int);
    #endif

    adder.c

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

    Example.java

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

    We compile in DLL

    cl /LD adder.c
    

    We use the utility jextractto 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;
    importstatic org.python.Python_h.*;
    importstatic org.python.pylifecycle_h.*;
    importstatic org.python.pythonrun_h.*;
    publicclassPythonMain{
        publicstaticvoidmain(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 .

    Also popular now: