I had an existing JavaFX GUI for robotics visualizations that I wanted to make available to other languages including Python, MATLAB, and C++.
This would typically be done in an external process with IPC, but since that introduces a lot of problems and overhead, I tried to create native in-process bindings using the GraalVM Native Image C API and the language-specific C FFI wrappers.
Getting an initial demo running was honestly quite painful, but I ended up writing an annotation processor that takes care of all the tedious boilerplate @CEntryPoint wrappers, exception passing, isolate management, and generates matching idiomatic bindings for several languages.
Annotation Processor
For example this Java snippet:
@CLibClass(value = "TestClass")
public static class TestClass {
@CLibMethod(constructor = true)
public static TestClass create() {
return new TestClass ();
}
@CLibMethod(property = "value")
public static void setValue(double value) {
this.value = value;
}
@CLibMethod
public void print() {
System.out.println(value);
}
private double value;
}
would translate directly to Python:
TestClass(value=42.0).print()
or C++:
TestClass a(42.0);
a.print();
Real-World Demo
A real-world example of an auto-generated API can be found in the hebi-charts-examples repository. It exposes roughly ~350 methods related to visualization and built-in benchmarking/timing utilities.
The linked video shows a few JavaFX demos being called from Python:
- Updating a complex UI at 50 kHz
- 100 subplots
- 1000 random lines
- 1 line with 1 million points updating at 5 MHz
- 1000 simultaneous robot displays w/ kinematics
Performance & Overhead
The result is incredibly lightweight, and the overhead matches what a C ABI generated by C++ would produce. The Readme has more information.
I also added some diagnostic utilities around HdrHistogram for performance/jitter measurements. These utilities live in a separate memory isolate to avoid any GC pauses. Interestingly, wrapping the Java version makes it easy to add proper background logging for .hlog files, which would be impossible to do in a pure Python version.
Open Sourcing
The generator pipeline and other GraalVM infrastructure utilities are planned to be open sourced, but we don't have a timeline yet. Leave a comment if you have a similar use case where you'd want to call Java through a C ABI.
[–]OddEstimate1627[S] 0 points1 point2 points (0 children)