MST

星途 面试题库

面试题:Rust中如何实现与C语言的基本ABI兼容

请阐述在Rust中实现与C语言基本ABI兼容的步骤,包括函数声明、数据类型对应等方面,并且给出一个简单的示例代码,展示Rust函数如何以C ABI兼容的方式被C语言调用。
12.9万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. 函数声明
    • 在Rust中,要实现与C语言基本ABI兼容,需要使用 extern "C" 修饰函数声明。extern "C" 表示该函数使用C语言的ABI(应用二进制接口)。
    • 例如,定义一个简单的加法函数:
    #[no_mangle]
    extern "C" fn add(a: i32, b: i32) -> i32 {
        a + b
    }
    
    • #[no_mangle] 是一个属性,它阻止Rust对函数名进行重整(name mangling),使得C语言可以使用原始的函数名来调用这个函数。
  2. 数据类型对应
    • Rust和C语言有一些数据类型可以直接对应:
      • 整数类型
        • Rust的 i8i16i32i64isize 分别对应C语言的 int8_tint16_tint32_tint64_tssize_t
        • Rust的 u8u16u32u64usize 分别对应C语言的 uint8_tuint16_tuint32_tuint64_tsize_t
      • 浮点类型
        • Rust的 f32 对应C语言的 float
        • Rust的 f64 对应C语言的 double
      • 指针类型
        • Rust的 *const T*mut T 分别对应C语言的 const T*T*
  3. 示例代码
    • Rust代码(文件名:lib.rs)
    #[no_mangle]
    extern "C" fn multiply(a: i32, b: i32) -> i32 {
        a * b
    }
    
    • 构建Rust代码为动态链接库
      • 在Rust项目的根目录下,确保有一个 Cargo.toml 文件,内容如下:
      [package]
      name = "rust_c_abi_example"
      version = "0.1.0"
      edition = "2021"
      
      [lib]
      crate - type = ["cdylib"]
      
      • 然后运行 cargo build --release,这会在 target/release 目录下生成动态链接库(.so 文件在Linux下,.dll 文件在Windows下,.dylib 文件在macOS下)。
    • C语言代码(文件名:main.c)
    #include <stdio.h>
    
    // 声明要调用的Rust函数
    extern int multiply(int a, int b);
    
    int main() {
        int result = multiply(3, 4);
        printf("The result of multiplication is: %d\n", result);
        return 0;
    }
    
    • 编译和运行C语言代码
      • 在Linux下,假设Rust生成的动态链接库名为 librust_c_abi_example.so,编译C代码的命令如下:
      gcc -L. -lrust_c_abi_example main.c -o main
      
      • 然后运行 ./main 即可看到结果。
      • 在Windows下,假设生成的动态链接库名为 rust_c_abi_example.dll,需要使用MinGW等工具来编译C代码,并且要确保 rust_c_abi_example.dll 在可搜索的路径中。
      • 在macOS下,假设生成的动态链接库名为 librust_c_abi_example.dylib,编译命令如下:
      gcc -L. -lrust_c_abi_example main.c -o main
      
      • 然后运行 ./main