如何将 Vec 转换为 C 友好的 *mut T?

2024-04-08

我有一个 Rust 库,它返回u8通过 FFI 将数组传递给 C 调用者。该库还可以在客户端使用完数组后处理删除数组的问题。库没有状态,因此客户端需要拥有该数组,直到将其传回库进行释放。

Using box::from_raw and boxed::into_raw会很好,但我无法弄清楚如何将数组转换为返回类型。


A Vec<T>由 3 个值描述:

  • 指向其第一个元素的指针,可以通过以下方式获得.as_mut_ptr() http://doc.rust-lang.org/std/slice/trait.SliceExt.html#tymethod.as_mut_ptr
  • 长度,可以通过以下方式获得.len() http://doc.rust-lang.org/collections/vec/struct.Vec.html#method.len
  • 容量,可以通过以下方式获得.capacity() http://doc.rust-lang.org/collections/vec/struct.Vec.html#method.capacity

对于C数组来说,容量是分配的内存大小,而长度是数组中实际包含的元素数量。两者都在计算数量T。您通常需要向 C 代码提供这 3 个值。

如果你想让它们相等,你可以使用.shrink_to_fit() http://doc.rust-lang.org/collections/vec/struct.Vec.html#method.shrink_to_fit根据分配器,尽可能减少向量的容量。

如果你归还所有权Vec<T>到你的C代码,不要忘记调用std::mem::forget(v)一旦你检索到前面描述的 3 个值,就可以避免它的析构函数在函数末尾运行。

之后,您可以创建回Vec从这 3 个值中使用from_raw_parts(..) http://doc.rust-lang.org/collections/vec/struct.Vec.html#method.from_raw_parts像这样:

let v = unsafe { Vec::<T>::from_raw_parts(ptr, length, capacity) };

当它的析构函数运行时,内存将被正确释放。请注意,这 3 个值必须正确才能正确释放内存。对于一个人来说这并不是很重要Vec<u8>,但是析构函数Vec将根据其包含的所有数据运行析构函数length.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 Vec 转换为 C 友好的 *mut T? 的相关文章

随机推荐