创建界面拉斯特C函数指针 [英] Create interface to C function pointers in Rust

查看:219
本文介绍了创建界面拉斯特C函数指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I might not have described my question title properly, please edit it if needed.

我想箱防锈接口 LXC库,这是用C语言编写。

I'm trying to crate a Rust interface to LXC library, which is written in C.

我已经成功地称为简单的功能,如 lxc_get_version lxc_container_new ,但我不能接触到<$描述的功能C $ C>结构lxc_container 块。

I have successfully called simple functions like lxc_get_version or lxc_container_new but I cannot get access to functions described in struct lxc_container block.

下面是我的code的一部分:

Here is an part of my code:

#[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函数指针,但没有运气。

I have managed that functions inside C structs is called function pointers. I've tried to google something like "Rust C function pointer", but without luck.

推荐答案

当你看到这样的事情(在C):

When you see something like this (in C):

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

这意味着结构取值包含一个名为˚F字段,它是指向一个功能。这并不意味着该库本身暴露了一个名为˚F功能。例如,这是有效的:

it means that struct S contains a field called f which is a pointer to a function. It does not mean that the library itself exposes a function called f. For example, this is valid:

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

Here struct instance s1 contains a pointer to some_function_1, and s2 contains a pointer to some_function_2.

当你写FFI拉斯特一些C库结合,你通常定义锈同行C结构。像锈的BindGen一些工具甚至可以自动做到这一点。你的情况,你将不得不这样写:

When you're writing FFI binding in Rust for some C library, you usually define Rust counterparts for C structures. Some tools like rust-bindgen can even do this automatically. In your case you will have to write something like this:

#[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 函数指针类型。你也可以写的externCFN(...) - GT; ... ,但C预选赛是默认设置,以便它不是必需的。

That is, weird-looking C function pointer types correspond to extern fn function pointer types in Rust. You could also write extern "C" fn(...) -> ..., but "C" qualifier is default so it is not required.

您将不得不写这样的事情来调用这些功能:

You will have to write something like this to call these functions:

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

您需要转换的引用到原始的指针,你也需要包装 self.is_defined_f 在括号中以方法调用和字段访问之间的歧义。

You need to cast a reference to a raw pointer and you also need to wrap self.is_defined_f in parentheses in order to disambiguate between method call and field access.

您可以找到更多关于FFI拉斯特这里。函数指针的解释很简单那里,虽然。

You can find more on FFI in Rust here. Function pointers are explained very briefly there, though.

这篇关于创建界面拉斯特C函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆