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
*/
相关推荐
不爱学英文的码字机器8 小时前
[鸿蒙PC命令行移植适配]移植rust三方库bottom到鸿蒙PC的完整实践
华为·rust·harmonyos
W_LuYi18510 小时前
Tauri + Rust + Vue 3 打造极速轻量桌面应用
java·开发语言·vue.js·rust
星栈10 小时前
Makepad 界面怎么做得更像产品,而不是示例
前端·rust
特立独行的猫a11 小时前
MQTT Client的Tauri应用移植到 OpenHarmony 鸿蒙 PC/ARM64 实践记录
mqtt·华为·rust·harmonyos·tauri·移植·鸿蒙pc
techdashen11 小时前
深入理解 Rust Futures:从零开始,一头扎到底
开发语言·后端·rust
fox_lht12 小时前
GPUI 框架完整学习教程
学习·rust·gpui
好家伙VCC12 小时前
Rust+Bioinfo:80ms极速SNP注释引擎
java·开发语言·算法·rust
吴佳浩1 天前
AI Infra 的真相:Go 没输,rust也不是取代
后端·rust·go
mit6.8241 天前
并发协调的代价
rust
不爱学英文的码字机器1 天前
[鸿蒙PC命令行移植适配]移植rust三方库sd到鸿蒙PC的完整实践
华为·rust·harmonyos