FFI, JNI, and passing *const u8's

I would like to pass data between rust and java using the FFI. I prefer dealing with raw bytes.

I found this crate: https://lib.rs/crates/c_vec

Therein, it shows this snippet:

extern crate libc;
extern crate c_vec;

use c_vec::{CVec, CSlice};

fn some_func(cvec: *mut libc::c_int, len: libc::c_uint) {
    // safe wrapper, you can pass a destructor with new_with_dtor() method
    let v = unsafe { CVec::new(cvec, len as usize) };
    // unsafe wrapper with no destructor
    let mut s = unsafe { CSlice::new(cvec, len as usize) };

    println!("cvec:   converted from c array: {:?}", v.as_ref());
    println!("cslice: converted from c array: {:?}", s.as_mut());
}

elsewhere, in the jni crate, I found this data type (https://docs.rs/jni/0.17.0/jni/sys/type.jbyteArray.html):

type jbyteArray = *mut _jobject;

With these in mind (open to using either, none, or other crates)... What should the extern function signature look like in rust? And how about java? Here's some pseudocode of what I think it should roughly look like:

Rust:

#[no_mangle]
extern fn send_bytes_to_rust(ptr: jbyteArray, len: libc::c_uint) { ... ? }
// side note: does *mut libc::c_int == jbyteArray?

Not even sure how the java version would look like. Want to ask the FFI experts about the best, safest way to pass bytes from java to rust, and rust to java.

Also: Using Vec::from_raw_parts would be preferable to use over CVec, but open to either

Found this possibility, which looks best: https://docs.rs/ffi-support/0.4.2/ffi_support/struct.ByteBuffer.html

Still, not sure how to setup java's native functions to ensure they map to ByteBuffer

1 Like