我有一个Rust库,通过FFI将数组返回给C调用者。该库还处理在客户端完成后删除数组。该库没有状态,因此客户端需要拥有该数组,直到将其传回库进行释放。
使用
使用
box::from_raw
和boxed::into_raw
会很好,但我无法弄清如何将数组转换为返回类型。Vec<T>
由三个值描述:
.as_mut_ptr()
获取。.len()
获取。.capacity()
获取。就 C 数组而言,容量是分配的内存大小,而长度则是实际包含在数组中的元素数量。两者都按 T
的数量计算。通常需要向 C 代码提供这三个值。
如果要使它们相等,可以使用.shrink_to_fit()
来缩小向量的容量,尽可能接近其大小(具体取决于分配器)。
如果将 Vec<T>
的所有权还给 C 代码,请在检索到前面描述的 3 个值后调用 std::mem::forget(v)
,以避免其析构函数在函数结尾运行。
之后,可以使用from_raw_parts(..)
从这三个值创建一个 Vec
,如下所示:
let v = unsafe { Vec::<T>::from_raw_parts(ptr, length, capacity) };
当其析构函数运行时,内存将被正确释放。请注意,为了正确释放内存,这3个值需要正确。对于Vec<u8>
来说并不是非常重要,但是Vec
的析构函数将根据其length
运行其包含的所有数据的析构函数。
Vec<T>
中获取一个C友好的指针(自包含),我使用了所述方法以及古老的C技巧,在数据前打包必要的元数据,并返回正确偏移量的指针给C调用者。通过反转该过程来丢弃内存。 - urubi