私はRustにCライブラリをラッピングしています。その関数の多くは、他の構造体へのポインタを持つ構造体へのポインタによってパラメータを受け取ります。オーバーヘッドを減らすために、RustデータをC構造体にマーシャリングした結果をキャッシュする機能を提供したいと思います。ここでRustのセマンティクスを移動する
は、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
の値は、の値がfoo
であることを指すように、またはNULLポインタがNone
の場合は指すように構成されます。
Cached
という値を移動する場合、直線memcpy
は不適切であり、さらにbar.p_foo
はリダイレクトする必要があります。これは、定義可能な移動セマンティクスでC++で確実にすることは簡単ですが、使用するまで「bar.p_foo
を設定しないでください」以外の解決策を提供していますか?このようにキャッシュされた値は、再利用されるよりも多く(またはそれに近い頻度でも)動かされるとは考えていません。これらの値を設定するには少しの作業が必要ですポインタ、特にネスト/チェインが深い/長い場合私はむしろBox
の部分構造をヒープ上に置いていません。明確にするために
は、ここで私はルーストに複製したいC++で書くことができるものです:生のポインタがそうであるように
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;
};
*は、 'Cached'の値が移動された場合です* *私は十分な情報を提供していないようです。移動したときに無効になる 'bar.p_foo'へのポインタを保持するのは何ですか? [this](https://play.rust-lang.org/?gist=53bf026d76e0665e2381&version=stable)のようなものはまったく役に立ちますか? – Shepmaster
'bar.p_foo' *は、オブジェクトが移動される場合に無効にされるポインタで、構造体自体の(部分の)フィールドを指します。私はC++で必要なものと同等のものを書くことで明確にします。 – jmegaffin