RustのFFIを活用してC言語関数を安全に呼び出す方法と手順

この記事では、RustのForeign Function Interface(FFI)を使用して、C言語の関数をRustから呼び出す方法を解説します。安全性や手順に焦点を当て、CとRustの統合を探求します。

FFIとは?

RustにおけるFFI(Foreign Function Interface)は、他のプログラミング言語(主にCやC++)で書かれたコードをRustから呼び出すための仕組みです。Rustは安全で制御された言語であり、CやC++といった低レベルの言語とのインターフェースを提供するために、FFIをサポートしています。

先に提供されたコードを振り返ってみると、Rustのプログラム内でC言語の関数を使用することを試みています。C言語の関数をRustから呼び出す際には、以下のステップを踏む必要があります。

  1. C言語のコードをラップする: C言語のコードを、Rustから呼び出せる形にラップします。ラップされた関数はRustのFFIに従って定義されます。
  2. Rustのコード内でラップした関数を使用: ラップしたC言語の関数を、Rustのコード内で呼び出します。
#[link(name = "mycalc", kind = "static")]
extern "C" {
    fn mul(a: i32, b: i32) -> i32;
}

fn main() {
    unsafe {
        let n = mul(30, 5);
        println!("{}", n);
        let n = mul(8, 80);
        println!("{}", n);
    }
}

このコードは、Rustのプログラム内でC言語のmul関数を呼び出しています。#[link] 属性を使用して、mycalc 静的ライブラリをリンクすることを指定しています。そして、extern "C" ブロック内で、C言語の関数 mul を宣言しています。

しかし、このコードのままではmul関数が正しくリンクされない場合があるため、前述のビルドスクリプトを使用してライブラリをビルドする必要があります。

cc::Build を使用したビルドスクリプトが提供されており、これによって mycalc.c ファイルがコンパイルされて mycalc 静的ライブラリが生成されます。その後、Rustのプログラム内で mul 関数を使用して、C言語の関数を呼び出しています。

以上のコードとビルドスクリプトを組み合わせて、C言語の関数をRustから呼び出すことができます。ただし、FFIを使用する際には注意が必要で、特に安全性とポインタ操作に関する問題に注意を払う必要があります。

ビルド関数の設定

提供していただいた mycalc.c のコードは、関数 mul を含むものですね。このファイルを静的ライブラリとしてビルドして、Rust プロジェクト内で使用するための手順を説明します。

  1. まず、プロジェクトのルートディレクトリに src フォルダを作成し、その中に mycalc.c ファイルを配置します。
  2. プロジェクトのルートディレクトリにある Cargo.toml ファイルと同じ階層に、build.rs というファイルを作成します。以下のように build.rs ファイルを作成します。
  3. このビルドスクリプトは、src フォルダ内の mycalc.c ファイルをコンパイルして mycalc 静的ライブラリを生成します。また、コンパイルが必要な場合にスクリプトが再実行されるように、cargo:rerun-if-changed メタデータを使用しています。
  4. プロジェクトのルートディレクトリにある Cargo.toml ファイルに、cc ライブラリのビルド依存関係を追加します。
fn main() { 
// Tell Cargo to rerun this script if the mycalc.c file changes 
println!("cargo:rerun-if-changed=src/mycalc.c");

// Compile the mycalc.c file into a static library 
cc::Build::new() .file("src/mycalc.c") .compile("mycalc");
}
[package]
name = "ffi_mul"
version = "0.1.0"
edition = "2021"

[dependencies]
libc = "0.2"

[build-dependencies]
cc = "1.0"  # カスタムビルドスクリプトで cc ライブラリを使用

これらの手順を実行し、mycalc.c を静的ライブラリとしてビルドするようにプロジェクトを設定してみてください。その後、Rust コード内で mycalc ライブラリを使用する部分に関する修正を行い、コンパイル・実行してみてください。

コメントを残す