遇到了一个需求,需要在 ffi 边界处解决异步问题。
用 async + ffi 会遇到很麻烦的生命周期问题,然后开始 Pin<Box<dyn X>>。
那我们不管生命周期不就好了。也就是 rust 的 ‘static。
那资源需要回收。我们设计一个小 GC 来实现。
GC 需要一个 preserve root + 记录表,在 rust 侧用 static Hashmap 来实现。
在 cpp 侧,只存对应对象的 id
也就是
cpp 构造函数 → 调 rust 构造 → rust 构造完后放进 hashmap,并只把 id 给 cpp
所有 cpp 的对象方法全通过 id 间接调用。
构造完了要析构。这里我们先检查 id 是否 == 0,不为零就在 hashmap 里取出对应 id 的 value drop 掉。
最巧妙的是移动构造函数。
整个过程对象都只有一份,但是持有的对象变了。
于是这期间不调用 drop,而是出让对象的 id。
而且还有好处,避免了 raw Pointer 所以甚至不用 unsafe。
对这种需求,更高效是用 ahash + dashmap