Back to Comprehensive Rust

Safe FFI Wrapper

src/unsafe-rust/exercise.md

latest3.1 KB
Original Source
<!-- Copyright 2023 Google LLC SPDX-License-Identifier: CC-BY-4.0 -->

Safe FFI Wrapper

Rust has great support for calling functions through a foreign function interface (FFI). We will use this to build a safe wrapper for the libc functions you would use from C to read the names of files in a directory.

You will want to consult the manual pages:

You will also want to browse the std::ffi module. There you find a number of string types which you need for the exercise:

TypesEncodingUse
str and StringUTF-8Text processing in Rust
CStr and CStringNUL-terminatedCommunicating with C functions
OsStr and OsStringOS-specificCommunicating with the OS

You will convert between all these types:

  • &str to CString: you need to allocate space for a trailing \0 character,
  • CString to *const c_char: you need a pointer to call C functions,
  • *const c_char to &CStr: you need something which can find the trailing \0 character,
  • &CStr to &[u8]: a slice of bytes is the universal interface for "some unknown data",
  • &[u8] to &OsStr: &OsStr is a step towards OsString, use OsStrExt to create it,
  • &OsStr to OsString: you need to clone the data in &OsStr to be able to return it and call readdir again.

The Nomicon also has a very useful chapter about FFI.

Copy the code below to https://play.rust-lang.org/ and fill in the missing functions and methods:

rust,should_panic,editable
# // Copyright 2023 Google LLC
# // SPDX-License-Identifier: Apache-2.0
#
// TODO: remove this when you're done with your implementation.
#![allow(unused_imports, unused_variables, dead_code)]

{{#include exercise.rs:ffi}}

{{#include exercise.rs:DirectoryIterator}}
        todo!()
    }
}

{{#include exercise.rs:Iterator}}
        todo!()
    }
}

{{#include exercise.rs:Drop}}
        todo!()
    }
}

{{#include exercise.rs:main}}
<details>

FFI binding code is typically generated by tools like bindgen, rather than being written manually as we are doing here. However, bindgen can't run in an online playground.

</details>