Skip to content

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

@AlonSpinner

Description

@AlonSpinner

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?",
          )); 
      }
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions