abs(3) をラップする

// Copyright 2026 Google LLC
// SPDX-License-Identifier: Apache-2.0

fn abs(x: i32) -> i32;

fn main() {
    let x = -42;
    let abs_x = abs(x);
    println!("{x}, {abs_x}");
}

このスライドでは、ラッパーを書くためのパターンを確立します。

関数シグネチャの外部定義を見つける 一致する関数を Rust の extern ブロック内に 書く 満たすべき安全性不変条件が何かを確認する その関数を安全としてマーク できるかどうかを判断する

これが まだ 動作しないことに注意してください。

extern ブロックを追加します:

#![allow(unused)]
fn main() {
// Copyright 2026 Google LLC
// SPDX-License-Identifier: Apache-2.0

unsafe extern "C" {
    fn abs(x: i32) -> i32;
}
}

多くの POSIX 関数が Rust で利用できるのは、Cargo がデフォルトで C 標準ライブラリ (libc)にリンクし、そのシンボルがプログラムのスコープに取り込まれるためである ことを説明します。

ターミナルで man 3 abs または ウェブページ を表示します。

関数シグネチャはその定義と一致していなければならないことを説明します: int abs(int j);

コードブロックを更新して C の型を使います。

#![allow(unused)]
fn main() {
// Copyright 2026 Google LLC
// SPDX-License-Identifier: Apache-2.0

use std::ffi::c_int;

unsafe extern "C" {
    fn abs(x: c_int) -> c_int;
}
}

理由を説明します: ffi::c_int を使うと、コードの移植性が向上します。 標準ライブラリがターゲットプラットフォーム向けにコンパイルされるとき、ビット幅は そのプラットフォームに応じて決定されます。C 標準によれば、c_int は、より一般的な i32 ではなく i16 として定義される場合があります。

(任意)c_int のドキュメント を表示し、それが i32 の型エイリアスであること を示します。

コンパイルを試みて、「error: extern blocks must be unsafe」というエラー メッセージを表示させます。

ブロックに unsafe キーワードを追加します:

#![allow(unused)]
fn main() {
// Copyright 2026 Google LLC
// SPDX-License-Identifier: Apache-2.0

use std::ffi::c_int;

unsafe extern "C" {
    fn abs(x: c_int) -> c_int;
}
}

学習者がこの変更の重要性を理解していることを確認します。型安全性やその他の 安全性の前提条件を守る必要があります。

再コンパイルします。

abs 関数に safe キーワードを追加します:

#![allow(unused)]
fn main() {
// Copyright 2026 Google LLC
// SPDX-License-Identifier: Apache-2.0

use std::ffi::c_int;

unsafe extern "C" {
    safe fn abs(x: c_int) -> c_int;
}
}

safe fn は、unsafe ブロックなしで abs を安全に呼び出せることを示す ものだと説明します。

参考用の完成版プログラム:

// Copyright 2026 Google LLC
// SPDX-License-Identifier: Apache-2.0

use std::ffi::c_int;

unsafe extern "C" {
    safe fn abs(x: c_int) -> c_int;
}

fn main() {
    let x = -42;
    let abs_x = abs(x);
    println!("{x}, {abs_x}");
}