1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-01-05 16:10:31 +02:00

Hint at the list of conversions in FFI exercise (#598)

I see people struggle a lot with guessing why they need to convert
between all these types. The explanations here should help with that.
This commit is contained in:
Martin Geisler 2023-04-27 14:45:15 -07:00 committed by GitHub
parent d394968eaf
commit 5074b1751c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -10,13 +10,36 @@ You will want to consult the manual pages:
* [`readdir(3)`](https://man7.org/linux/man-pages/man3/readdir.3.html)
* [`closedir(3)`](https://man7.org/linux/man-pages/man3/closedir.3.html)
You will also want to browse the [`std::ffi`] module, particular for [`CStr`]
and [`CString`] types which are used to hold NUL-terminated strings coming from
C. The [Nomicon] also has a very useful chapter about FFI.
You will also want to browse the [`std::ffi`] module. There you find a number of
string types which you need for the exercise:
| Types | Encoding | Use |
|----------------------------|----------------|--------------------------------|
| [`str`] and [`String`] | UTF-8 | Text processing in Rust |
| [`CStr`] and [`CString`] | NUL-terminated | Communicating with C functions |
| [`OsStr`] and [`OsString`] | OS-specific | Communicating 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 i8`: you need a pointer to call C functions,
- `*const i8` to `&CStr`: you need something which can find the trailing `\0` character,
- `&CStr` to `&[u8]`: you will ultimately return a slice of bytes,
- `&[u8]` to `&OsStr`: you can create an `OsString` from `&[u8]`. Use
[`OsStrExt`](https://doc.rust-lang.org/std/os/unix/ffi/trait.OsStrExt.html)
for this.
- `&OsStr` to `OsString`: you need to take ownership of the data before you call
`readdir` again.
The [Nomicon] also has a very useful chapter about FFI.
[`std::ffi`]: https://doc.rust-lang.org/std/ffi/
[`str`]: https://doc.rust-lang.org/std/primitive.str.html
[`String`]: https://doc.rust-lang.org/std/string/struct.String.html
[`CStr`]: https://doc.rust-lang.org/std/ffi/struct.CStr.html
[`CString`]: https://doc.rust-lang.org/std/ffi/struct.CString.html
[`OsStr`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html
[`OsString`]: https://doc.rust-lang.org/std/ffi/struct.OsString.html
[Nomicon]: https://doc.rust-lang.org/nomicon/ffi.html
Copy the code below to <https://play.rust-lang.org/> and fill in the missing