4 releases (stable)
2.0.1 | Mar 31, 2021 |
---|---|
2.0.0 | Dec 17, 2020 |
1.0.0 | Dec 16, 2020 |
0.1.0 | Dec 11, 2020 |
#83 in FFI
36,418 downloads per month
Used in 37 crates
(6 directly)
7KB
ffi-opaque
A macro generating correct opaque types.
What it does
Until RFC 1861 (Extern types) is implemented, representing opaque structs in Rust is hard, as decribed in the corresponding Nomicon section.
Yet, opaque structs are a common pattern, especially when working with C codebases through FFI.
ffi-opaque
provides the opaque!
macro which properly generates such types without having to think about the details.
Types generated by this macro:
- cannot be constructed outside of the module they are defined in
- ensure proper pointer alignment
- are
!Send
,!Sync
,!Unpin
- are FFI safe
In short, they match the behaviour of extern types, as currently implemented in rustc, as closely as possible.
Current differences:
- The generated types have a size of 0 (instead of being unsized)
- The generated types have an alignment of 1 (instead of being usized)
size_of_val
andalign_of_val
can be called on them
Usage example
Consider this example from the leveldb
C API:
typedef struct leveldb_options_t leveldb_options_t;
typedef struct leveldb_writeoptions_t leveldb_writeoptions_t;
leveldb_options_t* leveldb_options_create();
leveldb_writeoptions_t* leveldb_writeoptions_create();
It uses an opaque struct to avoid leaking structural details of its database options to a library linking to it. We can represent the opaque structs on the Rust side like this:
use ffi_opaque::opaque;
opaque! {
/// Documentation works!
pub struct leveldb_options_t;
/// Options used when writing data
pub struct leveldb_writeoptions_t;
}
extern "C" {
pub fn leveldb_options_create() -> *mut leveldb_options_t;
pub fn leveldb_writeoptions_create() -> *mut leveldb_writeoptions_t;
}
Possible future extensions
If extern
types become stabilised, this macro may adopt them.
License
MIT, see LICENSE file.
Acklowledgements
- David Tolnay (@dtolnay) for raising awareness of many subtle issues
- Nikolai Vasquez (@nvzqz) for implementing the final type and a number of checks