我有一个 Rust 库,它通过 FFI 将 u8
数组返回给 C 调用者。该库还处理在客户端使用完数组后删除数组。库没有状态,因此客户端需要拥有数组,直到它被传回库释放。
使用 box::from_raw
和 boxed::into_raw
会很好,但我无法弄清楚如何将数组转换为返回类型。
最佳答案
A Vec<T>
由 3 个值描述:
- 指向其第一个元素的指针,可以用
.as_mut_ptr()
获得。 - 一个长度,可以用
.len()
获得 - 可以通过
.capacity()
获得的容量
对于C数组来说,容量就是分配内存的大小,而长度就是数组实际包含的元素个数。两者都在计算 T
的数量.您通常需要为您的 C 代码提供这 3 个值。
如果你想让它们相等,你可以使用 .shrink_to_fit()
根据分配器,在向量上尽可能减少其容量。
如果您归还 Vec<T>
的所有权到您的 C 代码,不要忘记调用 std::mem::forget(v)
一旦您检索到前面描述的 3 个值,就可以在它上面进行操作,以避免在函数末尾运行其析构函数。
之后,您可以重新创建一个 Vec
从这 3 个值使用 from_raw_parts(..)
像这样:
let v = unsafe { Vec::<T>::from_raw_parts(ptr, length, capacity) };
当它的析构函数运行时,内存将被正确释放。请注意,这 3 个值需要正确才能正确释放内存。对于 Vec<u8>
来说不是很重要, 但 Vec
的析构函数将根据其 length
运行它包含的所有数据的析构函数.
关于rust - 如何将 Vec<T> 转换为 C 语言友好的 *mut T?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28758246/