Rust’s Foreign Function Interface (FFI) allows Rust code to interact with other programming languages, such as C, Python, and JavaScript. This enables developers to leverage existing libraries and improve performance by combining Rust’s speed with the flexibility of other languages. The following MCQs cover essential topics related to FFI, including calling C code, unsafe operations, and creating bindings.
1. Calling C Code from Rust
Which keyword is used in Rust to declare an external function, often for FFI with C? a) extern b) unsafe c) ffi d) foreign
In Rust, how can you link to a C function from an external library? a) By using extern crate b) By using extern with a #[link] attribute c) By defining the C function inside a mod block d) By using unsafe only
How would you call a C function that returns an integer in Rust? a) By declaring the function as fn c_func() -> i32; b) By using unsafe and calling c_func() directly c) By importing the C function with the use keyword d) By writing a wrapper function in Rust
What type of pointer does Rust use when calling C functions that return pointers? a) *mut T b) *const T c) &T d) Box<T>
How would you declare a C function that takes a pointer to an integer as an argument in Rust? a) fn c_func(x: &i32); b) fn c_func(x: *const i32); c) fn c_func(x: *mut i32); d) fn c_func(x: i32);
2. Rust’s Unsafe and FFI Safety
What does the unsafe keyword signify when calling FFI functions in Rust? a) The code will be compiled without type checks b) The function may violate memory safety rules c) The function is not allowed to access memory directly d) The function can only be called from the main thread
Why is Rust’s unsafe necessary for calling C code? a) To allow the use of raw pointers and manual memory management b) To ensure type safety c) To enable garbage collection d) To optimize function calls for performance
In Rust, what does unsafe allow you to do? a) Call functions with raw pointers b) Bypass the borrow checker c) Access fields of a struct directly without checking for ownership d) All of the above
When interfacing with C code in Rust, how does the compiler ensure safety? a) By automatically detecting unsafe code at compile time b) Rust does not ensure safety when calling C code c) By requiring manual checks in unsafe blocks d) Through runtime checks on every function call
What kind of errors can arise when using unsafe in FFI? a) Memory corruption b) Data races c) Undefined behavior d) All of the above
3. Creating Rust Bindings for C Libraries
What is the primary purpose of Rust bindings in FFI? a) To enable Rust to interact with C libraries b) To compile C code into Rust binaries c) To protect Rust code from memory leaks d) To automatically convert C code into Rust syntax
What tool is commonly used in Rust for generating bindings to C libraries? a) bindgen b) cargo ffi c) rust-bind d) cc-rs
Which Rust crate is often used to automate the generation of FFI bindings? a) ffi-lib b) bindgen c) cbind d) rust-bindings
How would you include a C library in a Rust project? a) Use #[link] attribute in an extern block b) Directly include the C code in the Rust project c) Modify the Rust build script with a C compiler option d) Automatically compile the C code during Rust compilation
In Rust, when linking to an external C library, which attribute is used to specify the library’s name? a) #[link(name = "libname")] b) #[lib("libname")] c) #[extern(name = "libname")] d) #[import("libname")]
4. Interfacing with Other Languages
How can Rust be interfaced with Python? a) By using PyO3 or rust-cpython crates b) By writing Python code directly in the Rust project c) By compiling Python code into Rust d) By using FFI directly with Python’s C API
What crate is commonly used to call Python code from Rust? a) pybind11 b) PyO3 c) rustpython d) pyrust
Which of the following is true when using FFI between Rust and JavaScript? a) Rust can directly execute JavaScript in the browser b) Rust can use WebAssembly to interact with JavaScript c) Rust cannot interact with JavaScript d) Rust and JavaScript can share memory directly without any intermediary
How does Rust interface with JavaScript in web applications? a) By using the wasm-bindgen crate b) By calling JavaScript functions directly in Rust c) By importing JavaScript libraries as Rust modules d) By compiling JavaScript into Rust code
Which feature does Rust offer for FFI between Rust and JavaScript? a) rust-web b) wasm-bindgen c) js-ffi d) cargo-js
5. Miscellaneous FFI Topics
In Rust, what type of function is typically used when interfacing with a C library? a) Unsafe functions b) Safe functions c) Public functions d) Static functions
How do you pass a string from Rust to C using FFI? a) By passing a &str reference b) By passing a String object c) By using a raw pointer to a null-terminated C string d) By using a &String reference
How does Rust ensure that a pointer passed to C is not null? a) Rust automatically checks all pointers b) It relies on the programmer to ensure null safety c) Rust uses a MaybeNull type for pointers d) Rust automatically converts None into a null pointer
In Rust, when using unsafe for FFI, what must be done to ensure proper memory management? a) Manually manage memory allocation and deallocation b) Use Rust’s garbage collector c) Trust the external code to handle memory d) Rust automatically manages memory in unsafe blocks
Which of the following is true about Rust’s approach to FFI safety? a) Rust guarantees memory safety even when calling unsafe code b) Rust performs runtime checks on all FFI calls c) Rust requires the developer to manually ensure FFI safety d) Rust does not allow FFI at all
How would you call a function from a C library that accepts a double argument in Rust? a) fn c_func(x: f64); b) fn c_func(x: i32); c) fn c_func(x: &f64); d) fn c_func(x: double);
What is the #[repr(C)] attribute used for in Rust FFI? a) To ensure that Rust structs are laid out in memory the same way as C structs b) To automatically generate C bindings c) To declare a function as callable from C d) To convert a C function into a Rust closure
How does the Rust toolchain assist in creating FFI bindings for C? a) By automatically generating the necessary C code b) By linking C libraries to Rust at compile time c) By providing a build.rs script to configure FFI d) By converting C syntax to Rust syntax
Which of the following is a primary challenge when working with FFI in Rust? a) Ensuring memory safety in unsafe code b) Writing bindings for incompatible C libraries c) Understanding Rust’s ownership and borrowing system d) All of the above
When calling FFI functions, which Rust feature should be avoided for memory safety? a) unsafe blocks b) extern declarations c) #[link] attributes d) & references
Answer Key (Tabular Form)
Qno
Answer
1
a) extern
2
b) By using extern with a #[link] attribute
3
a) By declaring the function as fn c_func() -> i32;
4
b) *const T
5
c) fn c_func(x: *mut i32);
6
b) The function may violate memory safety rules
7
a) To allow the use of raw pointers and manual memory management
8
d) All of the above
9
c) By requiring manual checks in unsafe blocks
10
d) All of the above
11
a) To enable Rust to interact with C libraries
12
a) bindgen
13
b) bindgen
14
c) Modify the Rust build script with a C compiler option
15
a) #[link(name = "libname")]
16
a) By using PyO3 or rust-cpython crates
17
b) PyO3
18
b) Rust can use WebAssembly to interact with JavaScript
19
a) By using the wasm-bindgen crate
20
b) wasm-bindgen
21
a) Unsafe functions
22
c) By using a raw pointer to a null-terminated C string
23
b) It relies on the programmer to ensure null safety
24
a) Manually manage memory allocation and deallocation
25
c) Rust requires the developer to manually ensure FFI safety
26
a) fn c_func(x: f64);
27
a) To ensure that Rust structs are laid out in memory the same way as C structs
28
c) By providing a build.rs script to configure FFI