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
*/
相关推荐
John_Rey6 小时前
Rust底层深度探究:自定义分配器(Allocators)——控制内存分配的精妙艺术
开发语言·后端·rust
勤奋的小小尘6 小时前
第三篇: Rust 结构体、Trait 和方法详解
rust
isyuah6 小时前
Rust Miko 框架系列(二):快速上手与基础示例
后端·rust
isyuah6 小时前
Rust Miko 框架系列(四):深入路由系统
后端·rust
星释9 小时前
Rust 练习册 10:多线程基础与并发安全
开发语言·后端·rust
2401_8603195216 小时前
【无标题】
开发语言·学习·rust
微小冷17 小时前
Rust实战教程:做一个UDP聊天软件
rust·udp·egui·聊天软件·rust教程·用户图形界面
星释20 小时前
Rust 练习册 :Rail Fence Cipher与栅栏密码
开发语言·算法·rust
Source.Liu1 天前
【Chrono】Cargo.toml 配置文件深度分析
rust·time
shykevin1 天前
Rust入门
开发语言·后端·rust