Dushistov / flapigen-rs

Tool for connecting programs or libraries written in Rust with other languages
BSD 3-Clause "New" or "Revised" License
787 stars 59 forks source link

Is there a way to use references in callbacks? #455

Open MrKekovichPersonal opened 8 months ago

MrKekovichPersonal commented 8 months ago

When I am trying to create callback with pointers, flapigen cannot convert &Type to java: rust code:

#[generate_interface]
pub trait GetScoreCallback {
    fn get_score(&mut self, network: &NeuralNetwork) -> f64;
}

generated interface:

foreign_callback!(
    callback GetScoreCallback {
        self_type GetScoreCallback;
        getScore = GetScoreCallback::get_score(& mut self , network : & NeuralNetwork)->f64;
    }
);

error:

  parsing of java-api-for-rust: src/generated/java_glue.rs.in failed
  error: Do not know conversion from such rust type '& NeuralNetwork' to Java type
        getScore = GetScoreCallback::get_score(& mut self , network : & NeuralNetwork)->f64;

However, when I am using references wtih class method - it works:

pub struct Something;
impl Something {
    #[generate_interface]
    pub fn something(net: &NeuralNetwork) {}
}
foreign_class!(
    class Something {
        fn Something::something(net : & NeuralNetwork); alias something;
    }
);

Copying network is a compute-intense process. Is there any way to solve this problem without copying?

Dushistov commented 7 months ago

@MrKekovichPersonal

Is there any way to solve this problem without copying?

You can copy, but use something like std::sync::Arc for this to make it cheap.

The problem is that in callback you call Java code from Rust. So there is need to pass reference to Rust object to Java with restricted lifetime.

But Java has no such thing as reference with restrited lifetime. So I can no see how to create "safe" way to do it. For example If flapigen generates Java class like NeuralNetworkReference, how can anybody prevent situation, when Java side user save object of type NeuralNetworkReference, somewhere and try to reuse it later?

That's why default binding require to pass ownership to Java side.