问题描述
我正在为 C API 编写 Rust 绑定。这个特定的 C API 有两个函数:f1
和 f2
。 f1
返回引用内部数据的句柄,该句柄在调用 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 (将#修改为@)