coralblocks / JavaToCppAndBack

Call Java from C++ and C++ from Java with a variety of old and new projects like JNI, JNA, JNR, FFM, JExtract, GraalVM, JNI-Bind, etc.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

JavaToCppAndBack

Call Java from C++ and C++ from Java with a variety of old and new projects like JNI, JNA, JNR, FFM, JExtract, GraalVM, JNI-Bind, etc.

This project is intended to be used as a quick reference on how to get going with Java and C++ integration, from both sides. It is a step-by-step guide, in the form of shell scripts (for Linux and MacOS) to compile and run the C++ and Java examples, so you don't have to guess anything. Just see "Hello World!" popping up in your terminal to celebrate! 🍾 🎉 🎊

MacOS

$ uname -a
Darwin MacBook-Air.local 22.6.0 Darwin Kernel Version 22.6.0: Wed Jul  5 22:17:35 PDT 2023; root:xnu-8796.141.3~6/RELEASE_ARM64_T8112 arm64

$ java -version
java version "21.0.1" 2023-10-17
Java(TM) SE Runtime Environment Oracle GraalVM 21.0.1+12.1 (build 21.0.1+12-jvmci-23.1-b19)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 21.0.1+12.1 (build 21.0.1+12-jvmci-23.1-b19, mixed mode, sharing)

$ clang++ --version
Apple clang version 14.0.3 (clang-1403.0.22.14.1)
Target: arm64-apple-darwin22.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

$ native-image --version
native-image 21.0.1 2023-10-17
GraalVM Runtime Environment Oracle GraalVM 21.0.1+12.1 (build 21.0.1+12-jvmci-23.1-b19)
Substrate VM Oracle GraalVM 21.0.1+12.1 (build 21.0.1+12, serial gc, compressed references)

$ jextract --version
jextract 21
JDK version 21.0.1+12-LTS-29
Apple clang version 14.0.3 (clang-1403.0.22.14.1)

Linux

$ uname -a
Linux cleveland 5.15.0-72-generic #79-Ubuntu SMP Tue Apr 18 16:53:43 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux

$ java -version
java version "21.0.1" 2023-10-17
Java(TM) SE Runtime Environment Oracle GraalVM 21.0.1+12.1 (build 21.0.1+12-jvmci-23.1-b19)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 21.0.1+12.1 (build 21.0.1+12-jvmci-23.1-b19, mixed mode, sharing)

$ clang++ --version
Ubuntu clang version 14.0.0-1ubuntu1.1
Target: aarch64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

$ native-image --version
native-image 21.0.1 2023-10-17
GraalVM Runtime Environment Oracle GraalVM 21.0.1+12.1 (build 21.0.1+12-jvmci-23.1-b19)
Substrate VM Oracle GraalVM 21.0.1+12.1 (build 21.0.1+12, serial gc, compressed references)

$ jextract --version
jextract 21
JDK version 21.0.1+12-jvmci-23.1-b19
Ubuntu clang version 14.0.0-1ubuntu1.1

Java calling C++

MacOS
# For Mac
$ ./bin/mac/jni/all.sh 2 Awesome
Hello CoralBlocks from JNI! => Awesome
Hello CoralBlocks from JNI! => Awesome
Linux
# For Linux
$ ./bin/linux/jni/all.sh 2 Awesome
Hello CoralBlocks from JNI! => Awesome
Hello CoralBlocks from JNI! => Awesome
MacOS
# For Mac
$ ./bin/mac/jna/all.sh 2 Awesome
Hello CoralBlocks from JNA! => Awesome
Hello CoralBlocks from JNA! => Awesome
Linux
# For Linux
$ ./bin/linux/jna/all.sh 2 Awesome
Hello CoralBlocks from JNA! => Awesome
Hello CoralBlocks from JNA! => Awesome
MacOS
# For Mac
$ ./bin/mac/jnr/all.sh 2 Awesome
Hello CoralBlocks from JNR! => Awesome
Hello CoralBlocks from JNR! => Awesome
Linux
# For Linux
$ ./bin/linux/jnr/all.sh 2 Awesome
Hello CoralBlocks from JNR! => Awesome
Hello CoralBlocks from JNR! => Awesome
(Thanks to Steven Curran)
MacOS
# For Mac
$ ./bin/mac/ffm/all.sh 2 Awesome
Hello CoralBlocks from FFM! => Awesome
Hello CoralBlocks from FFM! => Awesome
Linux
# For Linux
$ ./bin/linux/ffm/all.sh 2 Awesome
Hello CoralBlocks from FFM! => Awesome
Hello CoralBlocks from FFM! => Awesome
MacOS
# For Mac
$ ./bin/mac/ffm_jextract/all.sh 2 Awesome
Hello CoralBlocks from JExtract! => Awesome
Hello CoralBlocks from JExtract! => Awesome
Linux
# For Linux
$ ./bin/linux/ffm_jextract/all.sh 2 Awesome
Hello CoralBlocks from JExtract! => Awesome
Hello CoralBlocks from JExtract! => Awesome

C++ calling Java

MacOS
# For Mac
$ ./bin/mac/jni_jvm/all.sh 2 Awesome
Hello CoralBlocks from JNI-JVM! => Awesome
Hello CoralBlocks from JNI-JVM! => Awesome
Linux
# For Linux
$ ./bin/linux/jni_jvm/all.sh 2 Awesome
Hello CoralBlocks from JNI-JVM! => Awesome
Hello CoralBlocks from JNI-JVM! => Awesome
MacOS
# For Mac
$ ./bin/mac/graal/all.sh 2 Awesome
Hello CoralBlocks from GraalVM Native-Image! => Awesome
Hello CoralBlocks from GraalVM Native-Image! => Awesome
Linux
# For Linux
$ ./bin/linux/graal/all.sh 2 Awesome
Hello CoralBlocks from GraalVM Native-Image! => Awesome
Hello CoralBlocks from GraalVM Native-Image! => Awesome

C++ calling Java which calls back C++

  • Check the Java code
  • Check the C++ code that calls Java
  • Check the C++ code that receives the callbacks from Java
  • Check the C++ code header file for the C++ code above
MacOS
# For Mac
$ ./bin/mac/jni_callback/all.sh 2
Received callback from Java: 1683119040946
Received callback from Java: 1683119040947
Join returned, exiting C++ code...
Linux
# For Linux
$ ./bin/linux/jni_callback/all.sh 2
Received callback from Java: 1683119062956
Received callback from Java: 1683119062957
Join returned, exiting C++ code...

Java calling C++ which calls Java

MacOS
# For Mac
$ ./bin/mac/jni_bind/all.sh 2 Awesome
Hello CoralBlocks from JNI-Bind! => Awesome
Hello CoralBlocks from JNI-Bind! => Awesome
Linux

NOTE: For Linux make sure you have libc++-dev and libc++abi-dev installed.

    sudo apt-get install libc++-dev libc++abi-dev

# For Linux
$ ./bin/linux/jni_bind/all.sh 2 Awesome
Hello CoralBlocks from JNI-Bind! => Awesome
Hello CoralBlocks from JNI-Bind! => Awesome
Pure JNI x JNI-Bind
Pure JNI:
jclass helloWorldClass = env->FindClass("com/coralblocks/javatocppandback/jni_bind/HelloWorld");
jmethodID helloWorldConstructor = env->GetMethodID(helloWorldClass, "<init>", "()V");
jobject helloWorldObj = env->NewObject(helloWorldClass, helloWorldConstructor);
jmethodID sayHelloMethod = env->GetMethodID(helloWorldClass, "sayHello", "(ILjava/lang/String;)V");
env->CallVoidMethod(helloWorldObj, sayHelloMethod, x, msg);
JNI-Bind:
static constexpr jni::Class kClass {
    "com/coralblocks/javatocppandback/jni_bind/HelloWorld",
    jni::Method {
        "sayHello",
        jni::Return < void > {},
        jni::Params < jint , jstring> {}
    }
};

jni::LocalObject < kClass > helloWorld {}; // Constructs new instance.
helloWorld("sayHello", x, msg);

About

Call Java from C++ and C++ from Java with a variety of old and new projects like JNI, JNA, JNR, FFM, JExtract, GraalVM, JNI-Bind, etc.

License:Apache License 2.0


Languages

Language:C++ 91.9%Language:Shell 5.9%Language:Java 2.0%Language:C 0.1%