如何将生命周期限制在一个代码区域?

问题描述

我正在为 C API 编写 Rust 绑定。这个特定的 C API 有两个函数:f1f2f1 返回引用内部数据的句柄,该句柄在调用 f2 之前有效1

建模句柄生命周期约束的选项有哪些?最好在编译时强制执行,但如果这根本不可能,我也可以在运行时建立正确性。

解决方案可以假设以下限制:

  • 每次调用 f1 后都需要调用 f2,然后再次调用 f1。换句话说,任何一个函数都不能有两次或多次连续调用。
  • 所有函数都是从同一个线程调用的。

我尝试过的事情

我曾考虑使用 PhantomData 标记结构,但在这里不起作用,因为我无权访问句柄引用的基础数据。

我尝试过的另一个选择是从公共 API 表面完全删除 f2,并让客户端将函数传递到 f1 中,该函数可以安全地假设有效句柄:

pub fn f1(f: fn(h: &Handle) -> ()) {
    let h = unsafe { api::f1() };
    // Execute client-provided code
    f(&h);
    unsafe { api::f2() };
}

虽然通过永远不允许 Handle 逃脱 f1(我认为)来强制执行生命周期约束,但感觉它从客户那里夺走了太多控制权。这是库代码,我不想把它变成一个框架。

我考虑过的另一种替代方法是让客户将句柄移至 f2 以将所有权转回库实现:

pub fn f2(_h: Handle) {
    unsafe { api::f2() };
}

这似乎也有效(我认为),尽管它在 f2 的签名中引入了一个看似无关的参数,从而导致 API 有点混乱。

问题

这里我看不到的(规范)解决方案是什么?


1f2 不是严格的清理代码。它因不同的原因被调用,并且只会使 f1 返回的引用作为副作用无效。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)