2014-09-30 113 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