如何将Vec <T>转换为C-friendly*mut T?

uru*_*ubi 5 ffi rust

我有一个Rust库,它u8通过FFI 将数组返回给C调用者.该库还在客户端完成后处理数组.该库没有状态,因此客户端需要拥有该数组,直到它被传递回库以供释放.

使用box::from_raw并且boxed::into_raw会很好,但我无法解决如何将数组转换为返回类型的问题.

Lev*_*ans 6

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

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

如果您希望它们相等,则可以使用.shrink_to_fit()向量来尽可能地减小其容量,具体取决于分配器.

如果您Vec<T>将C代码的所有权归还给C代码,请不要忘记std::mem::forget(v)在检索到之前描述的3个值后调用它,以避免在函数结束时运行析构函数.

之后,您可以Vec使用以下方法从这3个值中创建回来from_raw_parts(..):

let v = unsafe { Vec::<T>::from_raw_parts(ptr, length, capacity) };
Run Code Online (Sandbox Code Playgroud)

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

  • 嗨,谢谢你的详细回复.它帮助我找到了一个可接受的问题解决方案:为了从'Vec <T>`获得一个c友好指针(自包含),我使用了概述的方法以及包装必要的古老C技巧数据之前的元数据,并将正确偏移的指针返回给C调用者.通过反转过程来完成内存丢弃. (2认同)