如何在不泄漏内存的情况下从C实现Rust结构和方法作为Vec?

如何在不泄漏内存的情况下从C实现Rust结构和方法作为Vec?,c,struct,binding,rust,ffi,C,Struct,Binding,Rust,Ffi,我正在为使用嵌入式构造函数和析构函数的C库编写Rust。C集管原始锈蚀代码: //不透明结构转换为枚举 发布枚举UdbEntity{} 发布枚举UdbReference{} ... 发布类型UdbEntity=*mut UdbEntity; 发布类型UdbReference=*mut UdbReference; ... //返回所有实体的非分配永久列表。此列表可能是 //用于需要并可能需要分配实体列表的地方 //安全地传递到udblistentyfree()。 发布日期(列表:*mut*mut

我正在为使用嵌入式构造函数和析构函数的C库编写Rust。C集管原始锈蚀代码:

//不透明结构转换为枚举
发布枚举UdbEntity{}
发布枚举UdbReference{}
...
发布类型UdbEntity=*mut UdbEntity;
发布类型UdbReference=*mut UdbReference;
...
//返回所有实体的非分配永久列表。此列表可能是
//用于需要并可能需要分配实体列表的地方
//安全地传递到udblistentyfree()。
发布日期(列表:*mut*mut UdbEntity,项目:*mut c_int);
//释放已分配的实体列表。
自由发布(列表:*多种内容);
...
//返回实体的所有引用的已分配列表。
//使用UDBLIStreeference()释放列表。
发布fn UDBLISTREFERNCE(实体:UdbEntity,
参考文献:*mut*mut UDB参考,
项目:*mut c_int);
//释放已分配的引用列表。
pub fn Udblistreeference(参考文献:*多个UdbReference);
这是安全防锈规范的实施,如下所示:

///实体的结构。
发布结构实体,
}
///实体列表的不透明结构。
pub struct Listenty,
}
///实体列表中实体的迭代器。

pub-struct-EntityIter-Drop for-listenty问题在于代码中有两个不相交的结构。一方面,您有一个
ListEntity
,它拥有一个
UdbEntity
的原始数组,并在需要时释放它;另一方面,您有一个
实体
,它包装了
UdbEntity
,但在
ListEntity
中没有任何引用

你有两个选择

  • udbenty
    的数组转换为
    实体的数组
    ,在这种情况下,您将能够创建它的切片。要做到这一点,它们需要具有相同的内存表示
  • 分别从
    UdbEntity
    创建
    实体
    的向量,并返回它们

  • 假设第一种方法是安全的,我会同意。如果没有,那么第二个可以工作。在这两种情况下,
    实体
    的数组都应由
    列表实体
    所有,以便正确管理内存。我可能会抛弃
    Entity
    中的
    PhantomData
    ,直接返回对它们的引用。

    我喜欢第一个版本,所以我没有尝试过。第二个版本呢?如果Vec归Listenty所有,那么对Vec的任何修改都会导致Listenty丢失。@saruman9如果
    Vec
    归Listenty所有,并且在外部通过引用可见,那么
    Vec
    就活不下去了-这是由锈迹所保证的。如果您需要
    Vec
    是可变的,那么我宁愿不使用它,而是在
    ListEntity
    本身上实现必要的特性。这里的问题是,
    Vec
    和底层结构需要同步修改,这是非常困难的。我在
    Deref
    中实现了从数组
    UdbEntity
    实体
    trait的转换(使用
    PhantomData
    ,因为使用一些FFI函数很难保持对
    实体的简单引用)。现在使用
    ListEntity
    这项工作。我也将尝试实现
    ListReference