2014-09-30 14 views
13

我可能沒有正確描述我的問題標題,請在需要時進行編輯。在Rust中爲C函數指針創建接口

我想箱子防鏽接口LXC library,這是寫在C.

我已經成功地被稱爲像lxc_get_versionlxc_container_new簡單的功能,但我不能訪問在struct lxc_container塊描述的功能。

這裏是我的代碼的一部分:

#[link(name = "lxc")] 
extern { 
    // LXC part 
    fn lxc_get_version() -> *const c_char; 
    fn lxc_container_new(name: *const c_char, configpath: *const c_char) -> LxcContainer; 

    // LXC container parts 
    fn is_defined(container: &LxcContainer) -> bool; 
} 

這裏是一個錯誤:

note: test.o: In function `LxcContainer::is_defined::heb2f16a250ac7940Vba': 
test.0.rs:(.text._ZN12LxcContainer10is_defined20heb2f16a250ac7940VbaE+0x3e): undefined reference to `is_defined' 

編輯:我成功是C結構的內部函數被調用的函數指針。我試圖谷歌類似「鏽C函數指針」,但沒有運氣。

回答

20

當你看到這樣的事情(在C):

struct S { 
    void (*f)(int, long) 
} 

這意味着結構S含有一種叫f領域這是一個指向函數的指針。這並不意味着庫本身公開了一個名爲f的函數。例如,這是有效的:

void some_function_1(int x, long y) { ... } 

void some_function_2(int a, long b) { ... } 

int main() { 
    struct S s1; s1.f = some_function_1; 
    struct S s2; s2.f = some_function_2; 
} 

這裏結構實例s1包含一個指向some_function_1,並s2包含一個指向some_function_2

當您在Rust的某個C庫中編寫FFI綁定時,通常會爲C結構定義Rust對應項。一些工具,如rust-bindgen甚至可以自動執行此操作。你的情況,你將不得不寫這樣的事:

#[repr(C)] 
struct LxcContainer { 
    name: *mut c_char, 
    configfile: *mut c_char, 
    // ... 
    numthreads: c_int, 
    // ... 
    is_defined_f: extern fn(c: *mut LxcContainer) -> bool, 
    state_f: extern fn(c: *mut LxcContainer) -> *const c_char, 
    // ... 
} 

也就是說,看起來怪怪的C函數指針類型對應extern fn函數指針類型生鏽。您也可以編寫extern "C" fn(...) -> ...,但"C"限定符是默認值,因此不是必需的。

你將不得不寫這樣的事情來調用這些函數:

impl LxcContainer { 
    fn is_defined_f(&mut self) -> bool { 
     unsafe { 
      (self.is_defined_f)(self as *mut LxcContainer) 
     } 
    } 
} 

你需要轉換的引用原始指針,你也需要包裝self.is_defined_f括號,以便方法調用之間的歧義和現場訪問。

你可以在Rust here的FFI上找到更多相關信息。雖然函數指針在那裏非常簡短地解釋。

+0

謝謝你的回答,我現在可以訪問函數指針。我寫了一個C表示結構和一個Rust表示的包裝器。不幸的是,我無法調用'is_defined',因爲我無法將LxcContainer結構作爲* LxcContainer函數傳遞。發生解引用錯誤。你能否在你的答案中加入一些函數指針調用的例子?謝謝。 – bbrodriges 2014-09-30 11:42:18

+0

@bbrodriges,對於最近的答覆感到抱歉,但我已經用一個如何調用存儲在結構字段中的函數的示例更新了我的答案。 – 2014-10-02 13:57:10