cbindgen
cbindgen copied to clipboard
Add java support (using JNA)
This builds on #853 and adds a new language backend capable of generating java bindings.
The generated bindings use JNA (I used the last version 5.13.0 while developing but this will probably work with earlier ones as well)
Most of the new code lives in bindgen/language_backend/java_jna.rs
and is pretty straightforward generation as most on the complicated things were done in the previous refactoring.
The test suite has been updated to generate and compile the bindings for java when running. On nice thing gained with this is the possibility to put a configuration file specific to a language alongside the standard one and the test will take this one instead of the default one if it exists (quite a few test use the header
config to add some more code inside the generated bindings, C or preprocessor code doesn't work well in a java source file :P)
All tests are green, but that doesn't mean all the generated bindings are correct, some cases may fail at runtime as I didn't test all cases in a real program. I did however generate and use the bindings on a non trivial lib I'm developing and they worked as expected.
rebased with the changes from #853
@fredszaq very cool! Currently I hand-author a Kotlin bridge class, e.g.:
package com.foo.bar
import android.view.Surface
class RustBridge {
init { System.loadLibrary("mylibrary") }
external fun enterFrame(rustObj: Long)
}
and use the following Rust code with the 'jni_fn' attribute to ensure the name is correct:
#[no_mangle]
#[jni_fn("com.foo.bar.RustBridge")]
pub fn enterFrame(_env: *mut JNIEnv, _: JClass, obj: jlong) {
let obj = unsafe { &mut *(obj as *mut WgpuCanvas) };
obj.enter_frame();
}
Will your backend be able to generate the kotlin bindings for this type? Also, will it handle the rust name conversion without needing the jni_fn crate? Thanks!
Hi @coolbluewater ! The generated bindings use JNA. JNA works a bit differently than JNI (which your example uses) even though JNA uses JNI under the hood.
When using JNI, the native code needs to be aware that it is called by a JVM. This is done for rust via the #[jni_fn()]
proc macro.
When using JNA, the native code doesn't need to be aware it is called from a JVM, as JNA is able to work with plain C compatible symbols. This means you don't have to have specific symbols for your lib for it to be able to be loaded from the jvm.
This means the rust code would probably look something like that
#[no_mangle]
pub fn enterFrame(obj: *mut WgpuCanvas) {
unsafe{ obj.enterFrame}
}
and the koltin code would look like that
class RustBridge {
fun enterFrame(rustObj: MyLib.WgpuCanvasByReference) {
MyLib.INSTANCE.entrerFrame(rustObj)
}
}
With the code for the class MyLib
beeing generated.
You can configure the name and the package of the generated class (actually the public api is an interface) in cbingen's config
[java_jna]
package = "my.package"
interface_name = "MyLib"
@fredszaq thanks for your response!
I need the JNIEnv and also need to pass jobject
s from Kotlin to Rust.
Is this possible in some way?
Not sure you want to mix JNI and JNA as the approaches are different and I'm not sure you'll be able to get access to the JNIEnv
via JNA.
Writing a java-jni
language backend that expects the rust code to be JNI aware could be a solution if you really need to access the JNIEnv
/jobject
s from the rust code. The the java-jna
language backend in this PR kinda expects you are using plain old C compatible symbols.
@emilio I rebased this with the latest master, following the merge of #942
I'm looking forward for this one to be merged. I'm working on a C# backend that has some common ground with Java.
Hi @emilio, I just rebased this on the latest master as there were some conflicts. It would be great if you have time to review again (I know this is a big piece). Regading length of various java types, a good documentation can be found here https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html We've been using bindings generated by this for a while at work and didn't have any problems with them