-
Notifications
You must be signed in to change notification settings - Fork 61
Description
Hi,
I believe similar questions have been asked before, but perhaps not pinpointing exactly my issue.
Thanks for taking the time to read this issue, and managing this library.
TLDR:
There are many examples of changing Java owned data with callbacks.
Is there a way to do the opposite, change data in Rust managed data with Java using callbacks?
Context:
I have a serial port in an android application that reads data and sends it to a "machine" built in Rust for processing.
This is a workaround, because normally the Rust machine is handeling the connection, and only exposes callbacks to different languages.
Example:
note: I have a typemap between u8 and i8 which works fine
========Rust Interface======
pub trait UsbSerialPortHandlerTraitFFI: Send {
fn ffi_open(&mut self) -> bool;
fn ffi_close(&mut self) -> bool;
fn ffi_write(&mut self, buffer: &[u8]) -> i32;
fn ffi_flush(&mut self) -> bool;
fn ffi_read(&mut self, buffer: &mut [u8]) -> i32;
}
foreign_callback!(callback UsbSerialPortHandlerTraitFFI {
self_type UsbSerialPortHandlerTraitFFI;
open_fn = UsbSerialPortHandlerTraitFFI::ffi_open(&mut self) -> bool;
close_fn = UsbSerialPortHandlerTraitFFI::ffi_close(&mut self) -> bool;
write_fn = UsbSerialPortHandlerTraitFFI::ffi_write(&mut self, buffer: &[u8]) -> i32;
flush_fn = UsbSerialPortHandlerTraitFFI::ffi_flush(&mut self) -> bool;
read_fn = UsbSerialPortHandlerTraitFFI::ffi_read(&mut self, buffer: &mut [u8]) -> i32;
});
=======Java Generated Interface via Flapigen=======
public interface UsbSerialPortHandlerTraitFFI {
boolean open_fn();
boolean close_fn();
int write_fn(byte [] buffer);
boolean flush_fn();
int read_fn(byte [] buffer);
}
=======Kotlin Interface Implementation of read_fn=======
override fun read_fn(buffer: ByteArray): Int
try {
val bytesRead = usbSerialPort.read(buffer, 200).toLong() // ms timeout
return bytesRead
} catch (e: IOException) {
return if (usbSerialPort.isOpen) {
-1
} else {
-2
}
}
}
=======Rust callback use : PROBLEM SHOWN HERE =======
fn read(&mut self, buffer: &mut [u8]) -> Result<usize, std::io::Error> {
let bytes_read = self.ffi_read(buffer); <================================THIS DOES NOT FILL BUFFER
if bytes_read >= 0 {
Ok(bytes_read as usize)
} else if bytes_read == -1 {
return Err(std::io::Error::new(
std::io::ErrorKind::TimedOut,
"Write timed out",
));
} else {
return Err(std::io::Error::new(
std::io::ErrorKind::BrokenPipe,
"Usb Detached?",
));
}
}