flapigen-rs
flapigen-rs copied to clipboard
c++/smart ptr and vec
Fix Vec<SmartPtr>
case.
Vec<Rc<RefCell<X>>
works while should not,
Vec<Arc<X>>
doesn't work.
I've recently bump into this. AFAIK the problem is, CRustForeignVec::from_vec
, should iterate through the Vec
and run box_object
on all items, before it creates CRustForeignVec
. Reverse operation should be done in drop_foreign_class_vec
. In fact, I can try to implement PR for this.
BTW, I have a problem with understanding those CRustVec
and CRustForeignVec
structs. If I understand correctly, the first one is intended for primitive types, like uint
, the second one, for SwigForeignClass
es. How about types that requires foreign_typemap
conversion, like tuples, Options, etc? Can they be used with Vec? How to adjust CRustForeignVec
to accept such types?
I've recently bump into this. AFAIK the problem is, CRustForeignVec::from_vec, should iterate through the Vec and run box_object on all items, before it creates CRustForeignVec. Reverse operation should be done in drop_foreign_class_vec. In fact, I can try to implement PR for this.
Not exactly. Case, when type T
exported as Box<T>
is special. Because it is possible to create C++ class from Vec<T>
directly, because of Box::into_raw
and &Vec<T>[index]
is the same thing.
But in case of Vec<T>
and OtherSmartPtr<T>
it is impossible to get the same thing from OtherSmartPtr::from_raw
and &Vec<T>[index]
(it would be the same type, but when you call into_raw
for &Vec[index]
it would be UB).
In case of Vec<OtherSmartPtr<T>>
and OtherSmartPtr<T>
, the problem is that index operation is very tricky. I suppose C++ RustForeignVec
in that case can not handle index operation in C++ part and should use Rust code for clone and into_raw calls.
BTW, I have a problem with understanding those CRustVec and CRustForeignVec structs. If I understand correctly, the first one is intended for primitive types, like uint, the second one, for SwigForeignClasses.
The main difference is step
field, it is impossible to calculate std::mem::size_of
in cross-compilation case in general. It is possible for primitive types, so CRustVec
is some kind of optimization.
Summary: CRustVec and CRustForeignVec are for cases when you can use directly Vec<T>
without additional memory allocations and without extra efforts.
For other cases: I just use foreign_class for Vec, like:
foreign_class!(
class Boo {
self_type Vec<Arc<Foo>>;
fn index(&self, i: usize) -> ...