[][src]Derive Macro ffishim_derive::FFIShim

#[derive(FFIShim)]
{
    // Attributes available to this derive:
    #[ffishim]
}

Mark a structure for use across the ffi boundary.

This procedural macro will generate a sister structure called FFIMyStruct. It contains the same fields in the same order, except in that they are represented as ffi compatible types: a CString instead of the original struct's String for example.

You can find the list of types supported by ffishim here. You can only use those types in fields of structures that derive FFIShim, as well as other structures that themselves derive FFIShim.

An implementation of from and try_into is provided for FFIMyStruct, which can be used for back-and-forth "translation." These translations are executed whenever MyStruct is passed to or returned from an ffishim_function, the macro which generates stubs around our functions. You should never have to deal with FFIMyStruct yourself at any time.

C ABI Violation: embedded structs

Aside from scalar types, nothing is directly embedded in the struct, it is dereferenced behind a pointer. This is because this project is originally written to work with Dart's new alpha ffi, and this version alpha does not support embeded structures yet.

This is also a reason this ffi shim currently performs many more dynamic memory allocations than would be necessary provided we could use straight-forward ffi structure embeds.

Opaque feature

If you want to embed structures which have no ffi shim, you can mark them as opaque like this:

This example is not tested
#[derive(FFIShim)]
pub struct MyStruct {
    #[ffishim(opaque)]
    not_ffi_compatible: ::std::collections::HashMap<i64, i64>,
}

Here, the sister structure still features the field in rust, but it is stored in its native rust form. This should make it virtually unusable from across the ffi boundary, but we will not loose it.

In this case, the not_ffi_compatible field will be carried by the corresponding ffi shim FFIMyStruct, but it will not be formatted in any way, and will not be consumable from across the ffi boundary.

If you have many of such fields in the structure, you might be interested in making the whole structure opaque, in which case none of its fields are exposed:

This example is not tested
#[derive(FFIShim)]
#[ffishim(opaque)]
pub struct MyStruct {
    not_ffi_compatible: ::std::collections::HashMap<i64, i64>,
}