Crate sawp_ffi_derive[−][src]
A proc_macro for generating accessors for members of structs and enums
Accessors are compatible with cbindgen for creating FFI
Attributes: #[sawp_ffi(...)]
copy
: ReturnType
instead of*const Type
. Useful for enums withrepr(Integer)
skip
: Don't generate accessor for member. Note: only public members will have accessors.u8_flag
: Returnu8
instead of*const Type
. Requires member type to be using bitflags macro.type_only
: Only generate enumType
and<enum>_get_type
. Won't generate accessors for variant fieldsprefix
: Prefix for all functions. eg:<prefix>_<struct_name>_get_<field>
Note: accessors are functions so they will be in snake_case. Struct and Enum names will be converted to snake_case in function names.
Structs
Accessors for structs are of the form:
#[no_mangle] pub unsafe extern "C" fn struct_name_get_member_name(*const Struct) -> *const Member;
of if either the Member type is a field convertible to a C_FIELD by cbindgen or has the sawp_ffi copy attribute:
#[no_mangle] pub unsafe extern "C" fn struct_name_get_member_name(*const Struct) -> Member;
Example
extern crate bitflags; use bitflags::bitflags; use sawp_ffi_derive::GenerateFFI; #[repr(u16)] #[derive(Copy, Clone)] pub enum Version { Version1 = 0x0100, Version1_1 = 0x0101, Version2 = 0x0200, } bitflags! { pub struct FileType: u8 { const READ = 0b0000_0000; const WRITE = 0b0000_0001; } } #[derive(GenerateFFI)] #[sawp_ffi(prefix = "sawp")] pub struct MyStruct { pub num: usize, #[sawp_ffi(copy)] pub version: Version, #[sawp_ffi(u8_flag)] pub file_type: FileType, private: usize, #[sawp_ffi(skip)] pub skipped: usize, pub complex: Vec<u8>, }
Will result in:
#[no_mangle] pub unsafe extern "C" fn sawp_my_struct_get_num(my_struct: *const MyStruct) -> usize; #[no_mangle] pub unsafe extern "C" fn sawp_my_struct_get_version(my_struct: *const MyStruct) -> Version; #[no_mangle] pub unsafe extern "C" fn sawp_my_struct_get_file_type(my_struct: *const MyStruct) -> u8; #[no_mangle] pub unsafe extern "C" fn sawp_my_struct_get_complex(my_struct: *const MyStruct) -> *const Vec<u8>;
Enums
Enums will have a flat, C compatible, enum created to define their type.
Users of the accessors should first call <enum>_get_type()
to determine the enum type
and then use the appropriate accessors to get that type's fields.
These enums will have the same name as the base enum with Type appended to it.
Note: All enum accessors can return null if the accessor isn't of the correct variant type
Accessors for enums are of the form:
To get the type:
#[no_mangle] pub unsafe extern "C" fn enum_name_get_type(* const Enum) -> EnumType;
For variants with named fields:
#[no_mangle] pub unsafe extern "C" fn enum_name_get_variant_name_member_name(e: *const Enum) -> *const Field;
For variants with a single unnamed field:
#[no_mangle] pub unsafe extern "C" fn enum_name_get_variant_name(e: *const Enum) -> *const Field;
For variants with multiple unnamed fields, N is the field index:
#[no_mangle] pub unsafe extern "C" fn enum_name_get_variant_name_N(e: *const Enum) -> *const Field;
Unit variants (variants with no fields) will not have any accessors.
Example
extern crate bitflags; use bitflags::bitflags; use sawp_ffi_derive::GenerateFFI; #[repr(u16)] #[derive(Copy, Clone)] pub enum Version { Version1 = 0x0100, Version1_1 = 0x0101, Version2 = 0x0200, } bitflags! { pub struct FileType: u8 { const READ = 0b0000_0000; const WRITE = 0b0000_0001; } } #[derive(GenerateFFI)] pub enum MyEnum { UnnamedSingle(u8), UnnamedMultiple(u8, u16), Named { a: u8, b: Vec<u8>, #[sawp_ffi(u8_flag)] file_type: FileType, }, Empty, }
Will result in:
#[repr(C)] pub enum MyEnumType { UnnamedSingle, UnnamedMultiple, Named, Empty, } #[no_mangle] pub unsafe extern "C" fn my_enum_get_unnamed_single(my_enum: *const MyEnum) -> *const u8; #[no_mangle] pub unsafe extern "C" fn my_enum_get_unnamed_multiple_0(my_enum: *const MyEnum) -> *const u8; #[no_mangle] pub unsafe extern "C" fn my_enum_get_unnamed_multiple_1(my_enum: *const MyEnum) -> *const u16; #[no_mangle] pub unsafe extern "C" fn my_enum_get_named_a(my_enum: *const MyEnum) -> *const u8; #[no_mangle] pub unsafe extern "C" fn my_enum_get_named_b(my_enum: *const MyEnum) -> *const Vec<u8>; #[no_mangle] pub unsafe extern "C" fn my_enum_get_named_file_type(my_enum: *const MyEnum) -> *const u8;
Derive Macros
GenerateFFI | Derive macro for autogenerated accessors compatible with cbindgen See library documentation for usage examples |