หนึ่งในความสามารถที่ทรงพลังของ Rust คือการติดต่อกับภาษาอื่นผ่าน FFI (Foreign Function Interface) โดยเฉพาะ C/C++ ซึ่งเป็นพื้นฐานของระบบจำนวนมาก
การทำ FFI ช่วยให้คุณสามารถ:
- เรียกใช้ไลบรารี C/C++ จากโค้ด Rust
- ให้ Rust ทำหน้าที่เป็นไลบรารีให้ C/C++
- ทำงานร่วมกับ native library เช่น OpenSSL, SQLite, หรือระบบ low-level
พื้นฐานของ FFI
FFI ใน Rust ต้องใช้ unsafe
เสมอ เพราะ compiler ไม่สามารถตรวจสอบ safety ของโค้ดข้ามภาษาได้
extern "C" { fn abs(input: i32) -> i32; } fn main() { unsafe { println!("abs(-10) = {}", abs(-10)); } }
คำสั่ง extern "C"
ระบุ ABI (Application Binary Interface) แบบ C
เชื่อม Rust กับ C
1. เขียนฟังก์ชัน C
// libmath.c int double_input(int x) { return x * 2; }
// header file: libmath.h int double_input(int x);
2. สร้าง shared object
“`bash
gcc -c -fPIC libmath.c -o libmath.o
gcc -shared -o libmath.so libmath.o
3. เขียน Rust เรียก C
// main.rs extern "C" { fn double_input(x: i32) -> i32; } fn main() { unsafe { let result = double_input(5); println!("Result from C: {}", result); } }
4. เพิ่ม Rust build script (optional)
toml
Cargo.toml
[dependencies]
[build-dependencies]
cc = “1.0”
// build.rs fn main() { println!("cargo:rustc-link-lib=dylib=math"); println!("cargo:rustc-link-search=native=."); }

Expose Rust ให้ C ใช้
#[no_mangle] pub extern "C" fn triple_input(x: i32) -> i32 { x * 3 }
ฟังก์ชันที่ export ออกไปต้องมี #[no_mangle]
เพื่อป้องกันการเปลี่ยนชื่อสัญลักษณ์
Rust กับ C Struct
// mystruct.h typedef struct { int x; int y; } Point;
#[repr(C)] pub struct Point { pub x: i32, pub y: i32, }
การใช้ #[repr(C)]
ทำให้ Rust เรียง memory layout เหมือน C
เรียก C++ จาก Rust
Rust ไม่รองรับ ABI ของ C++ โดยตรง แต่สามารถใช้ bridge ผ่าน extern “C” หรือใช้เครื่องมือเช่น cxx
, bindgen
ใช้ crate cxx
// Rust #[cxx::bridge] mod ffi { extern "C++" { include!("calc.hpp"); fn multiply(a: i32, b: i32) -> i32; } }
แล้วให้เขียน C++ ฝั่งหนึ่งและใช้ build.rs เชื่อม
การจัดการ Memory ระหว่างภาษา
- ต้องชัดเจนว่าใคร allocate และใคร free
- ห้าม free จาก Rust ถ้า allocate จาก C โดยไม่เข้าใจ layout
ปลอดภัยสุดคือ copy ข้อมูลข้าม boundary แล้ว free ในที่ของตัวเอง
การใช้ bindgen
bindgen
ใช้ generate Rust binding จาก header file C อัตโนมัติ
#bash
cargo install bindgen
bindgen wrapper.h -o src/bindings.rs
ข้อดีของ FFI
- Reuse code C/C++ เดิมได้
- เชื่อมกับ native library ได้ง่าย
- ใช้ Rust เพื่อเขียน core logic แล้ว expose ไปยังภาษาอื่น
ข้อเสีย
- ไม่ปลอดภัย (ต้องใช้ unsafe)
- debug ยากขึ้น
- มีค่าใช้จ่ายทางด้าน performance และ ABI mismatch ได้
บทสรุป
FFI เป็นสะพานเชื่อมระหว่าง Rust และโลกของภาษาอื่น โดยเฉพาะ C/C++
หากคุณต้องการทำงานกับระบบที่มีไลบรารีเก่า หรืออยาก optimize บางส่วนด้วย Rust แล้วเรียกจากภาษาอื่น — FFI คือคำตอบ
แต่จงระวัง: คุณต้องมีความรู้ทั้งสองฝั่ง และควบคุม memory ให้แม่นยำ เพราะ compiler จะไม่ช่วยคุณอีกต่อไป
เรียนรู้ FFI อย่างลึกซึ้ง แล้ว Rust จะกลายเป็นอาวุธระดับโลกของคุณ