The ReprC trait

ReprC is the core trait around safer_ffi's design.

Indeed,

a function can only be marked #[ffi_export] if its parameters and returned value are all ReprC.

When is a type ReprC?

A type is ReprC:

  • when it is a primitive type with a C layout (integer types, floating point types, char, bool, non-zero-sized arrays, and extern "C" callbacks),
Function pointers do not support lifetimes yet

Due to a type-system limitation, function pointers that use lifetimes are not ReprC yet. Only function pointers with a non-generic signature can be made ReprC, but this requires defining a newtype wrapper. A convenience macro is planned to be added to automate that step.

#[derive_ReprC]

You can (safely) make a custom type be ReprC by adding the #[derive_ReprC] attribute on it.

Supported types

Currently, the supported types for the attribute are:

  • a (non-zero-sized) #[repr(C)] struct having only ReprC fields.

    • or a #[repr(transparent)] tuple struct wrapper around a ReprC type.
  • a field-less #[repr({integer})] enum (A "C-like" enum).

  • an arbitrary type that you will only use through (pointer) indirection.

    This leads to the "opaque object" pattern, based on an undefined / forward declaration: typedef struct MyOpaque MyOpaque_t;

    use ::safer_ffi::prelude::*;
    
    #[derive_ReprC]
    #[ReprC::opaque]
    struct MyOpaque {
        /* anything goes here */
    }
    

The following are not yet implemented

  • a #[repr(C)] union.

  • Some kind of #[repr(to_be_determined)] enum which would be allowed to have fields (thus leading to repr_c::Option and repr_c::Result types, which ought to get rid of any need to use out-parameters).