我在 Rust 中包装了一个 C 库,它的许多函数通过指向结构的指针获取参数,这些结构本身通常具有指向其他结构的指针。为了减少开销,我想提供将 Rust 数据编组到 C 结构中的结果缓存的能力。
以下是 C 库可能期望某些参数的示例:
#[repr(C)]
struct Foo {
x: i32,
y: f32
}
#[repr(C)]
struct Bar {
p_foo: *const Foo,
z: bool
}
我想象一个拥有的“缓存”版本会是什么样子:
struct Cached {
foo: Option<Foo>,
bar: Bar
}
的p_foo
字段bar
将被构造为指向 内的Some
值foo
,或者如果存在则为空指针None
。
当然,这里的问题是,如果Cached
要移动 的值,则顺子memcpy
将不合适,并且bar.p_foo
还需要重定向。这在 C++ 中很容易确保,它具有可定义的移动语义,但是除了“在使用之前不要设置”之外,Rust 是否提供了解决方案bar.p_foo
?虽然这样做肯定会奏效,但我认为这些缓存值的移动频率不会超过(甚至接近于)它们被重用的频率,而且设置这些缓存值需要做一些工作指针,尤其是在嵌套/链接很深/很长的情况下。我也不想把Box
子结构放在堆上。
为了澄清,这是我可以用 C++ 编写的,我想在 Rust 中复制:
struct Foo {
int x;
float y;
};
struct Bar {
Foo const*pFoo;
bool z;
};
// bear with me while I conjure up a Maybe for C++
class Cached {
public:
// would have appropriate copy constructor/assignment
Cached(Cached &&other) {
m_foo = other.m_foo;
m_bar = other.m_bar;
if(m_foo.isJust()) {
m_bar.pFoo = &m_foo.value();
} // else already nullptr
}
// similar move assignment
private:
Maybe<Foo> m_foo;
Bar m_bar;
};