mcpField
R
rust-ffi-safe-wrappers

rust-ffi-safe-wrappers

github.com/lvtd-llc開発161 回インストール8 週間前に更新
リポジトリ

rust-ffi-safe-wrappers について

外部インターフェースを安全にラップする Rust 開発者向けスキルです。生のバインディングを unsafe 境界に分離し、Rust API の所有権、エラー、後処理、パニック動作を明確にします。

主な機能

  1. 01生のバインディングと安全なラッパーを分離
  2. 02ABI と所有権の契約を確認
  3. 03C 互換のデータ配置を定義
  4. 04C 文字列とハンドルを管理
  5. 05外部エラーを Result に変換
  6. 06パニックとコールバックの動作を定義

活用シーン

  1. 01C ライブラリ向け Rust バインディングのレビュー
  2. 02外部ハンドルに後処理を備えたラッパーを作成
  3. 03文字列とバッファーの所有権を確認
  4. 04Rust 2024 の FFI 宣言を監査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/lvtd-llc/skills --skill rust-ffi-safe-wrappers

インストール後、Claude Code で/rust-ffi-safe-wrappersを入力して読み込まれたか確認します。

同梱ファイルagents/openai.yamlreferences/ffi-boundary-patterns.md

詳細

Rust FFI セーフラッパー

所有権、ライフタイム、エラー、クリーンアップを明確にする Rust API で、外部インターフェースをラップする際にこのスキルを使用します。FFI コードは生の境界では unsafe とし、通常の Rust 呼び出し元には安全に使えるようにします。

基本的なワークフロー

  1. 生の宣言とセーフラッパーを分離します。生の unsafe extern バインディングは、小さな非公開モジュールに配置します。
  2. 外部ヘッダーまたはドキュメントを参照して、ABI、型のレイアウト、呼び出し規約、所有権、null 許容性、スレッド処理、エラー規約を確認します。
  3. モダンな Rust、特に Rust 2024 エディションのコードでは、unsafe extern "C" ブロックを使用します。安全性が条件に左右される項目は修飾しないか、明示的に unsafe とし、すべての Rust 入力に対して呼び出しが安全な場合に限り、個々の extern 項目に safe を付けます。
  4. ABI 境界を越える構造体と列挙型には #[repr(C)] を使用します。Rust 専用のレイアウト型を C に公開しないでください。
  5. C に渡す所有 NUL 終端文字列には CString を、借用する C 文字列には CStr を使用します。任意の C メモリを Rust 所有のものとして扱わないでください。
  6. 生のハンドルは、非公開フィールドと、対応する外部デアロケーターを使った Drop クリーンアップを備える Rust 型でラップします。
  7. Rust のパニックが extern "C" 境界を越えないようにします。意図的に "C-unwind" を使用する場合に限り、パニックを捕捉するか、アンワインドを許可する ABI を公開します。

ラッパーのルール

FFI バインディングを追加またはレビューする前に、references/ffi-boundary-patterns.md を読んでください。

  • 整数サイズを推測する代わりに、core::ffi または std::ffi の C 型を優先します。
  • 外部エラーコードは、ラッパー境界で Rust の Result に変換します。
  • 役立つ場合は、null 許容ハンドルを内部で Option<NonNull<T>> として表し、呼び出し元には安全な Rust 型を公開します。
  • コンパイラーが関係を認識できない場合は、通常の参照または PhantomData を使って、借用値のライフタイムを所有者に結び付けます。
  • 外部ライブラリでプロセス全体のセットアップが必要な場合は、OnceLock、LazyLock、または Once を使って、初期化とシャットダウンを冪等にします。
  • 大規模または変更頻度の高い C ヘッダーには bindgen を、Rust API を C に公開する場合には cbindgen を使用します。ただし、生成された unsafe シグネチャも必ずレビューしてください。

Rust 2024 の構文チェック

unsafe extern "C" {
    pub fn library_open(path: *const core::ffi::c_char) -> *mut RawHandle;
    pub fn library_close(handle: *mut RawHandle);
    // Mark an item `safe` only when calling it is valid for all Rust inputs:
    // pub safe fn library_version() -> core::ffi::c_int;
}

// SAFETY: This exported symbol name is unique for this library.
#[unsafe(no_mangle)]
pub extern "C" fn plugin_version() -> core::ffi::c_int {
    1
}

no_mangle、export_name、link_section などの unsafe 属性は、Rust 2024 エディションのコードでは unsafe(...) 形式が必要です。シンボルの一意性やリンカーの動作が契約の一部である場合は、SAFETY コメントを記載します。

レビューチェックリスト

  • 生のバインディングは非公開にするか、セーフラッパーと明確に分離します。
  • すべてのポインターパラメーターについて、null 許容性と所有権の規則を文書化します。
  • すべての割り当ては、同じ側、または明示的に対応付けられたデアロケーターによって解放されます。
  • 文字列とバッファーについて、長さ、エンコーディング、NUL バイト要件を維持します。
  • 境界を越えるパニック、コールバック、スレッドの動作を明確に定めます。

コメント