Skip to content
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

Feature Request / Question: Filling Rust owned data with Callback from Java #466

Open
AlonSpinner opened this issue Dec 10, 2024 · 0 comments

Comments

@AlonSpinner
Copy link

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?",
          )); 
      }
  }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant