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 小时前
被10个终端窗口逼疯后,我用Rust写了个零依赖跨平台终端Agent启动神器
rust·agent
alwaysrun1 天前
Rust中模式匹配
rust·match·模式匹配·if let·while let·值绑定
编码浪子2 天前
Dioxus hot-dog 总结
rust
光影少年2 天前
rust生态及学习路线,应用领域
开发语言·学习·rust
Kiri霧2 天前
Linux下的Rust 与 C 的互操作性解析
c语言·开发语言·rust
大鱼七成饱3 天前
Rust 多线程编程入门:从 thread::spawn 步入 Rust 并发世界
后端·rust
ServBay4 天前
Rust 1.89更新,有哪些值得关注的新功能
后端·rust
MOON404☾4 天前
Rust程序语言设计(5-8)
开发语言·后端·rust
Vallelonga4 天前
Rust 中的数组和数组切片引用
开发语言·rust
Kiri霧4 天前
Rust模式匹配详解
开发语言·windows·rust