Taaitaaiger / jlrs

Julia bindings for Rust
MIT License
408 stars 21 forks source link

Opaque Type Vector #133

Closed ju6ge closed 3 weeks ago

ju6ge commented 1 month ago

Hey,

first of, thanks for this awesome project and the amount of effort put into this. Really amazing! Thank you.

I am hitting a problem an can not figure out how to solve it. I have multiple Opaque Types that I want to export to Julia via jlrs. But some of the Opaque types expect other opaque types as function arguments. In the most simple case handling this is straight forward using TypedValue. But what if I have a function that expects a list of multiple TypedValue.

Consider the following Situation:


mod downstream {
  struct Item {
    // …
  }
  struct Container {
     items: Vec<Item>
  }
  impl Container {
    pub fn new(items: Vec<Item>) -> Self {
      Self {items}
   }
  }
}

pub struct JlrsItem(downstream::Item) //new type pattern

unsafe impl OpaqueType for JlrsItem {}

pub struct JlrsContainer(downstream::Container)

unsafe impl OpaqueType for JlrsContainer {}

impl JlrsContainer {
   pub fn new(items: SimpleVector) -> JlrsResult<TypedValueRet<Self>> {
      // this is where I am struggeling
      let item: SimpleVectorContent<'_,'_, TypedValueRef<JlrsItem>> = items.typed_data()?;
      …
   }
}

I could probably work around this by using some kind of Builder Type pattern and add the values one by one, but that seems a bit cumbersome.

Kind regards, ju6ge

Taaitaaiger commented 4 weeks ago

You'll need to create either a foreign type to do that by implementing ForeignType, or use an Array instead. The GC has to be "taught" how to find references to Julia data in foreign types by implementing a custom mark function. If you create a Vector{Any}, you can sidestep that issue entirely.

ju6ge commented 3 weeks ago

Hey, thanks for the answer, I have now just circumvented the problem, by just adding things to a rust Vector one by one, that way it works and I can just handle the situation from the julia side.