rust - 如何将 Vec<T> 转换为 C 语言友好的 *mut T?

标签 rust ffi

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

使用 box::from_rawboxed::into_raw 会很好,但我无法弄清楚如何将数组转换为返回类型。

最佳答案

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

对于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/

相关文章:

macros - 是否可以定义一个宏来从数字生成所有枚举值的静态数组?

rust - 如何在 Rust 中捕获信号

haskell - 无法在 Haskell 中链接 FFI 库

haskell - Haskell 中 FFI 调用的类型自动转换

winapi - 调用 GetBinaryTypeA 时出现段错误

haskell - 如何将 Haskell 库与 Rust 项目静态链接?

json - 使用 serde_json 序列化带有非字符串键的映射

rust - 对于列出为实现的类型,未实现IntoHandlerError

c - 如何调用需要一个指向缓冲区的双指针的 Rust 函数

c++ - FFI 的 Ruby 扩展