-
Notifications
You must be signed in to change notification settings - Fork 314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add java support (using JNA) #857
base: master
Are you sure you want to change the base?
Conversation
12e10bf
to
2f48952
Compare
d8b3cfa
to
23313a2
Compare
rebased with the changes from #853 |
23df5f2
to
a9b2175
Compare
a9b2175
to
dde67d2
Compare
dde67d2
to
83874a5
Compare
@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? |
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 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
and the koltin code would look like that
With the code for the class You can configure the name and the package of the generated class (actually the public api is an interface) in cbingen's config
|
83874a5
to
c463fea
Compare
@fredszaq thanks for your response! |
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 Writing a |
c463fea
to
8f7cbfa
Compare
src/bindgen/config.rs
Outdated
deserialize_enum_str!(Language); | ||
|
||
impl Language { | ||
pub(crate) fn typedef(self) -> &'static str { | ||
match self { | ||
Language::Cxx | Language::C => "typedef", | ||
Language::Cython => "ctypedef", | ||
_ => unimplemented!(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's list JNA explicitly. But why can't it hit it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this typedef function is only used by the enum code
src/bindgen/ir/enumeration.rs
Outdated
@@ -721,6 +721,7 @@ impl Enum { | |||
write!(out, "{}enum {}", config.style.cython_def(), tag_name); | |||
} | |||
} | |||
_ => unimplemented!(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same, let's at least keep the language listed. But why can't it be reached? Worth a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is really C (and derivatives) oriented, even though it lives in the IR, the impl of enums for java ends up not using this at all
IntKind::B8 => "byte", | ||
IntKind::B16 => "short", | ||
IntKind::B32 => "int", | ||
IntKind::B64 => "long", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also not right, this doesn't seem guaranteed to be 64 bytes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
long is 64 bytes in java
IntKind::B8 => JnaIntegerType::Byte, | ||
IntKind::B16 => JnaIntegerType::Short, | ||
IntKind::B32 => JnaIntegerType::Int, | ||
IntKind::B64 => JnaIntegerType::Long, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also not right.
IntKind::Short => JnaIntegerType::Short, | ||
IntKind::Int => JnaIntegerType::Int, | ||
IntKind::Long => JnaIntegerType::NativeLong, | ||
IntKind::LongLong => JnaIntegerType::Long, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LongLong is not Long, for sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Long is 64 bytes in java (the C long is NativeLong)
I'm looking forward for this one to be merged. I'm working on a C# backend that has some common ground with Java. |
This builds on mozilla#853 and adds a new language backend capable of generating java bindings. The generated bindings use [JNA](https://github.com/java-native-access/jna) (I used the last version 5.13.0 while developping 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 straightfowards 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 possibilibty to put a configuration file specific to a language alongside the stardard 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 developping and they worked as expected.
043a569
to
6a9ff03
Compare
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 |
It would be great if we could have typed enums support. |
This is very rough: https://github.com/Larkooo/cbindgen/tree/java-jna-backend but this should handle typed enums with unions and decorates them with a tag which is the original generated enum |
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.