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 天前
使用Webassembly实现图片压缩
前端·javascript·性能优化·rust·wasm·webassembly
古城小栈1 天前
rust中的两大枚举:Option 和 Result
开发语言·rust
许泽宇的技术分享1 天前
打破AI调用壁垒:Antigravity Tools如何用Rust+Tauri重构你的AI工作流
人工智能·重构·rust
问道飞鱼2 天前
【Rust开发知识】Actix-web 开发环境搭建完整教程
开发语言·前端·rust·actix-web
古城小栈2 天前
PyO3 库全介绍
python·rust
古城小栈2 天前
Rust 中符号语法 一文全晓
开发语言·后端·rust
古城小栈2 天前
Rust 模块管理与文件联动
开发语言·后端·rust
古城小栈2 天前
内存对决:rust、go、java、python、nodejs
java·golang·rust
superman超哥3 天前
Rust 错误处理模式:Result、?运算符与 anyhow 的最佳实践
开发语言·后端·rust·运算符·anyhow·rust 错误处理
Tony Bai4 天前
高并发后端:坚守 Go,还是拥抱 Rust?
开发语言·后端·golang·rust