Небезопасные внешние функции
Внешние функции для доступа из Rust можно объявить с помощью unsafe extern. Это небезопасно, потому что компилятор не может рассуждать об их поведении. Функции, объявленные в блоке extern, должны быть помечены как safe или unsafe в зависимости от того, есть ли у них предусловия для безопасного использования:
// Copyright 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0
use std::ffi::c_char;
unsafe extern "C" {
// `abs` не работает с указателями и не имеет требований безопасности.
safe fn abs(input: i32) -> i32;
/// # Safety
///
/// `s` должен быть указателем на строку C, оканчивающуюся NUL, которая допустима и
/// не изменяется на протяжении этого вызова функции.
unsafe fn strlen(s: *const c_char) -> usize;
}
fn main() {
println!("Absolute value of -3 according to C: {}", abs(-3));
// SAFETY: Мы передаём указатель на строковый литерал C, который допустим на
// протяжении всей работы программы.
unsafe {
println!("String length: {}", strlen(c"String".as_ptr()));
}
}
- Раньше Rust считал все внешние функции небезопасными, но это изменилось в Rust 1.82 с появлением блоков
unsafe extern. absдолжна быть явно помечена какsafe, потому что это внешняя функция (FFI). Вызов внешних функций представляет проблему только тогда, когда эти функции делают что-то с указателями, что может нарушить модель памяти Rust, но в целом любая функция C может иметь неопределённое поведение при любых произвольных обстоятельствах."C"в этом примере — это ABI; доступны и другие ABI.- Обратите внимание, что нет проверки того, что сигнатура функции Rust совпадает с сигнатурой определения функции, — это ответственность разработчика!