Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Rust中创建C函数指针的接口_C_Rust - Fatal编程技术网

在Rust中创建C函数指针的接口

在Rust中创建C函数指针的接口,c,rust,C,Rust,我可能没有正确描述我的问题标题,如果需要请编辑它 我试图用C语言编写一个生锈的界面 我成功地调用了一些简单函数,如lxc\u get\u version或lxc\u container\u new,但我无法访问struct lxc\u container块中描述的函数 以下是我代码的一部分: #[link(name = "lxc")] extern { // LXC part fn lxc_get_version() -> *const c_char; fn lxc

我可能没有正确描述我的问题标题,如果需要请编辑它

我试图用C语言编写一个生锈的界面

我成功地调用了一些简单函数,如
lxc\u get\u version
lxc\u container\u new
,但我无法访问
struct lxc\u 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'

EDIT:我管理过C结构中的函数称为函数指针。我曾尝试在谷歌上搜索“Rust C function pointer”之类的东西,但运气不好。

当你看到这样的东西时(在C中):

这意味着struct
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
包含指向
某些函数\u 1
的指针,
s2
包含指向
某些函数\u 2
的指针

在为某些C库编写Rust中的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函数指针类型对应于Rust中的
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\u f
括在括号中,以消除方法调用和字段访问之间的歧义


你可以在Rust中找到更多关于FFI的信息。函数指针的解释非常简单。

谢谢您的回答,我现在可以访问函数指针了。我已经为C表示编写了一个结构,并围绕它编写了一个Rust表示的包装器。不幸的是,我无法调用
is_defined
,因为我无法将LxcContainer结构传递给函数*LxcContainer。出现解引用错误。你能在你的答案中添加一些函数指针调用的例子吗?谢谢。@bbrodriges,很抱歉回复太晚,但我已经用一个如何调用存储在struct字段中的函数的示例更新了我的答案。
impl LxcContainer {
    fn is_defined_f(&mut self) -> bool {
        unsafe {
            (self.is_defined_f)(self as *mut LxcContainer)
        }
    }
}