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

 鲁小姐就不用围脖 发布于 2022-12-19 06:35

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

我正在尝试为LXC库创建一个Rust接口,这是用C语言编写的.

我已成功调用简单函数lxc_get_version,lxc_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结构中的函数称为函数指针.我试过谷歌像"Rust C函数指针",但没有运气.

1 个回答
  • 当你看到这样的东西时(在C中):

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

    它意味着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;
    }
    

    这里struct实例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于Rust中的函数指针类型.你也可以写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的FFI的更多信息.但是,函数指针在那里非常简单地解释.

    2022-12-19 07:11 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有