rust - 删除存储在 FFI 中的 Rust void 指针

标签 rust

我正在包装一个 C API,它允许调用者通过函数调用设置/获取任意指针。通过这种方式,C API 允许调用者将任意数据与 C API 对象之一相关联。此数据不用于任何回调,它只是一个指针,用户可以将其隐藏起来并在以后获取。

我的包装器结构为包含此指针的 C 对象实现了 Drop 特性。我希望能够做的,但不确定是否可能,如果包装器结构下降时指针不为空,则正确下降数据。我不确定如何从原始 c_void 指针恢复正确的类型。

我想到的两个选择是

  1. 在包装器中实现这两个调用的行为。不要对 C API 进行任何调用。
  2. 不要尝试为这些函数提供任何类型的更安全的接口(interface)。记录指针必须由包装器的调用者管理。

我想做的事可行吗?如果没有,是否有针对此类情况的普遍接受的做法?

最佳答案

由于以下原因,天真 + 全自动方法是不可能的:

  • 释放内存不会调用 drop/deconstructors/...:C API 可用于具有应正确解构的对象的语言,例如C++ 或 Rust 本身。因此,当您仅存储一个内存指针时,您不知道要调用正确的函数(您既不知道哪个函数也不知道调用约定是什么样的)。

  • which memory allocator?: 内存分配和释放不是一件小事。您的程序需要从操作系统请求内存,然后以智能方式管理这些资源,以提高效率和正确性。这通常由图书馆完成。在 Rust 的情况下,使用 jemalloc (但 can be changed )。因此,即使您要求 API 调用者仅传递 Plain Old Data (这应该更容易破坏)你仍然不知道调用哪个库函数来释放内存。仅使用 libc::free 是行不通的(它可以但可能会失败)。

解决方案:

  • dealloc 回调:您可以要求 API 用户设置一个额外的指针,比方说一个 void destruct(void* ptr) 函数。如果这个不为 NULL,则在放置期间调用该函数。您还可以使用 int 作为返回类型,以在销毁出错时发出信号。在这种情况下,您可以例如 panic!

  • 全局回调:假设您要求您的用户仅传递 POD(普通旧数据)。要知道调用内存分配器的哪个 free 函数,您可以请求用户注册一个全局 void (*free)(void* ptr) 指针,该指针在降低。您也可以将其设为可选。

关于rust - 删除存储在 FFI 中的 Rust void 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38289355/

相关文章:

reference - 有没有办法将引用类型克隆到拥有的类型中?

generics - 无法推断默认泛型类型参数

unix - Gold 无法从静态库创建可重定位目标文件

rust - fn item 和 fn pointer 之间的实际区别是什么?

authentication - 如何创建具有基于 session 身份验证的 actix-web HttpServer?

arrays - 访问嵌套数组中的值

module - 错误[E0277] : the trait bound `my_struct::MyStruct: my_trait::MyTrait` is not satisfied

performance - 为什么我的Rust程序比等效的Java程序慢?

file-io - 在 Rust 1.x 中读写文件的实际方式是什么?

macros - 是否可以创建一个宏来计算扩展项目的数量?