Rust- FFI (Foreign Function Interface)

Foreign Function Interface (FFI) is a mechanism that allows code written in one language to call code written in another language. With FFI, a program can use libraries and capabilities from another language, often allowing for performance optimizations or the use of specific features not available in the original language.

In the context of Rust, FFI is used for calling functions written in other languages, such as C or C++, or allowing code from other languages to call Rust functions. Rust provides a variety of tools and features to facilitate this interaction.

For instance, if you have a function defined in C, you can use Rust's FFI to call it like so:

rust 复制代码
extern "C" {
    fn abs(input: i32) -> i32;
}

fn main() {
    unsafe {
        println!("Absolute value of -3 according to C: {}", abs(-3));
    }
}

In the above code, the extern "C" block is defining an interface to a C function, and then we're calling that function within an unsafe block. This is typically considered an unsafe operation as Rust can't guarantee the safety of external functions.

Similarly, you can expose Rust functions to other languages:

rust 复制代码
#[no_mangle]
pub extern "C" fn call_from_c() {
    println!("Just called a Rust function from C!");
}

In the code above, pub extern "C" is defining a Rust function with a C interface, and #[no_mangle] tells the Rust compiler not to change the name of the function, allowing it to be found from other languages.

In conclusion, while Rust's safety and expressiveness often make it possible to avoid FFI, it remains a powerful tool when you need to use libraries from other languages or perform certain performance optimizations.

A comprehensive case is as follows:

rust 复制代码
use std::os::raw::c_int;    // 32bit
use std::os::raw::c_double; // 64bit

extern "C" {
    fn abs(num: c_int) -> c_int;
    fn sqrt(num: c_double) -> c_double;
    fn pow(num: c_double, power: c_double) -> c_double;
}

fn main() {
    let x: i32 = -127;
    println!("abs({}) = {}", x, unsafe {
        abs(x)
    });

    let n: f64 = 3.0;
    let p: f64 = 2.0;
    println!("pow({}, {}) = {}", n, p, unsafe {
        pow(n, p)
    });

    let y: f64 = 64.0;
    println!("sqrt({}) = {}", y, unsafe {
        sqrt(y)
    });

    let z: f64 = -64.0;
    println!("sqrt({}) = {}", z, unsafe {
        sqrt(z)
    });
}

/*
output:
    abs(-127) = 127
    pow(3, 2) = 9
    sqrt(64) = 8
    sqrt(-64) = NaN
*/
相关推荐
孙启超1 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust
mikuyyds1 天前
geo-toolbox 水文插件算法解析:从 Muskingum 到 Muskingum-Cunge
算法·rust·gis
PC2005-cloud1 天前
Rust学习笔记:模块系统——mod、use、pub与多文件项目
rust
Amos_Web1 天前
Rspack 源码解析(十二):JavaScript Chunk 是如何被渲染出来的
前端·rust·源码
柯南46681 天前
【AI开发之Rust】第 14 课:网络请求与 JSON —— reqwest + serde
rust·编程语言
恋喵大鲤鱼2 天前
Rust 格式化输出占位符详解
rust
孙启超2 天前
【AI开发之Rust】第 13 课:async/await 与 tokio 异步运行时
开发语言·后端·rust
小道士写程序2 天前
Rust + Axum + MySQL + SQLx
rust
mikuyyds2 天前
geo-toolbox 插件算法解析:RUSLE 与 MUSLE 的工程化落地
算法·rust·gis