2016-05-23 25 views
4

xcb作成のウィンドウでカイロサーフェスを使用しようとしています。私はCの例だけでなく、Rust XCBとCairoバインディングを持っています。私はほとんど終わりましたが、このエラーは私にとって謎のままです。rust-xcbから `roots`を呼び出すときに「十分に長生きしない」というエラーが発生する

マイコード:

let visual = find_visual(&conn, screen.root_visual()).unwrap(); 

そして、このようなエラー得る:

src/main.rs:56:19: 56:24 error: `setup` does not live long enough 
src/main.rs:56  for screen in setup.roots() { 
           ^~~~~ 
src/main.rs:54:97: 68:2 note: reference must be valid for the lifetime 'a as defined on the block at 54:96... 
src/main.rs:54 fn find_visual<'a>(conn: &'a xcb::Connection, visual: xcb_visualid_t) -> Option<Visualtype<'a>> { 
src/main.rs:55  let setup: Setup<'a> = conn.get_setup(); 
src/main.rs:56  for screen in setup.roots() { 
src/main.rs:57   let d_iter: DepthIterator = screen.allowed_depths(); 
src/main.rs:58   for depth in d_iter { 
src/main.rs:59    for vis in depth.visuals() { 
       ... 
src/main.rs:55:45: 68:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 55:44 
src/main.rs:55  let setup: Setup<'a> = conn.get_setup(); 
src/main.rs:56  for screen in setup.roots() { 
src/main.rs:57   let d_iter: DepthIterator = screen.allowed_depths(); 
src/main.rs:58   for depth in d_iter { 
src/main.rs:59    for vis in depth.visuals() { 
src/main.rs:60     if visual == vis.visual_id() { 
       ... 

そしてscreendepth変数に同じエラーを

fn find_visual<'a>(conn: &'a xcb::Connection, visual: xcb_visualid_t) -> Option<Visualtype<'a>> { 
    let setup: Setup<'a> = conn.get_setup(); 
    for screen in setup.roots() { 
     let d_iter: DepthIterator = screen.allowed_depths(); 
     for depth in d_iter { 
      for vis in depth.visuals() { 
       if visual == vis.visual_id() { 
        println!("Found visual"); 
        return Some(vis) 
       } 
      } 
     } 
    } 
    None 
} 

私はこれを呼び出します。

setupが十分に長生きしていない」理由を説明することはできますか?私が理解しているように、setupは、機能returnオプションで破壊され、機能制限なく使用することができます。

get_setup()コード:

pub fn get_setup(&self) -> Setup { 
    unsafe { 

     let setup = xcb_get_setup(self.c); 
     if setup.is_null() { 
      panic!("NULL setup on connection") 
     } 
     mem::transmute(setup) 
    } 
} 
+0

rust-xcbのソースを見ると、私は生涯の注釈を見つけることができません。特に、セットアップ構造体には何もありません。 –

+0

@SebastianRedl私は寿命があるのを見てhttp://rtbo.github.io/rust-xcb/src/xcb/xproto.rs.html#1516 – dimcha

+0

ああ、古いAatchのレポを見ていました。 –

答えて

2

バインディングの生涯注釈が故障しているように見えます。ここroots()です:機能には何の注釈が存在しないため、これは暗黙のうちに

impl<'a> Screen<'a> { 
    pub fn <'b> roots(&'b self) -> ScreenIterator<'b> { 
     unsafe { 
      xcb_setup_roots_iterator(self.ptr) 
     } 
    } 
} 

として注釈そして、これが間違っていることを

impl<'a> Screen<'a> { 
    pub fn roots(&self) -> ScreenIterator { 
     unsafe { 
      xcb_setup_roots_iterator(self.ptr) 
     } 
    } 
} 

注意。返されたScreenIteratorには、生存期間'aが明示的に注釈されている必要があります。これは、元の接続の存続期間であり、XCBは、渡されたすべてのポインタが生涯にわたって接続の存続期間に拘束されるという規則を持っています。。ラッパー型base::StructPtrのためにこれは発電機のスクリプトは、このためにアカウントを調整する必要があるあなたはクレートの問題を提出すべきである意味、リクエスタから

UPD: @SebastianRedlは正しかった問題が未設定の寿命です。 rust-xcb crateの次の寿命の変更により、コードを正常にコンパイルできます。

impl<'a> Setup<'a> { 
    pub fn roots(&self) -> ScreenIterator<'a> { 
     unsafe { 
      xcb_setup_roots_iterator(self.ptr) 
     } 
    } 
} 

impl<'a> Depth<'a> { 
    pub fn visuals(&self) -> VisualtypeIterator<'a> { 
     unsafe { 
      xcb_depth_visuals_iterator(self.ptr) 
     } 
    } 
} 

impl<'a> Screen<'a> { 
    pub fn allowed_depths(&self) -> DepthIterator<'a> { 
     unsafe { 
      xcb_screen_allowed_depths_iterator(self.ptr) 
     } 
    } 
} 
+0

私はxcb ffiジェネレータを変更し、 "error:生涯名前" a "を取得して、すでにスコープ内にある生涯の名前をシャドーします"。インプラントの場合と同じ生涯名前を使用することはできないようです。<'a>画面<'a> – dimcha

+1

重要なのは、新しい生涯を宣言するのではなく、既存の生涯を使用することです。だから、 "pub fn roots(& 'a self) - > ScreenIterator <'a> {...}"のようになり、 "pub fn roots <'a>(...)"にはなりません。 –

関連する問題