Files
sarasacw-omrf/assets/c-friendly-ffi-design/rust-side/misc.md
T
2026-08-17 22:04:56 +08:00

3.2 KiB

Miscellaneous Stuff

Two-Project Workspace Structure

When writing FFI, we require you to develop with two projects using the Rust workspace mechanism. For example:

  • An ordinary Rust library project named foobar. In this project you write your library logic in a pure Rust way.
  • An FFI-specific library project named foobar-ffi (the name does not have to be exactly this; you may choose any name that fits your need). This project references foobar within the workspace, writes the relevant code according to this design, wraps foobar into a form suitable for FFI export, and finally exports it in FFI form.

Panic Policy

In the FFI project, we enforce that every panic causes the process to exit immediately, just like executing std::abort in C++. So you need to specify the following in the Cargo.toml of the FFI project, so that this feature is enabled only in the production environment (that is, the release mode):

[profile.release]
panic = "abort"

The reason for enabling this feature only in the release mode is that in the debug mode you may need to perform operations such as stack tracing to debug the project, and enabling this feature would make such operations impossible.

You may think this operation would cause the user's process to crash frequently. But a well-designed library should be able to catch all recoverable errors and try not to trigger any unrecoverable errors. This operation forces developers to design a well-functioning library and eliminate potential errors during the development stage.

Artifact Type

The build artifact of the FFI project should meet the requirements of the C language FFI. So you need to specify the following in the Cargo.toml of the FFI project to set the produced artifact type:

[lib]
crate-type = ["cdylib"]

Module Organization

In the FFI project, do not try to pile everything into lib.rs. You need to make reasonable use of the Rust module mechanism. For example:

  • When combining multiple Rust types to create an opaque struct dedicated to FFI, you can write it in a module named like wrapper (the name does not have to be exactly this; you may choose any name that fits your need).
  • When re-wrapping Rust types, you can write it in a module named like ffi_types (the name does not have to be exactly this; you may choose any name that fits your need).

lib.rs should contain only the following:

  • User-defined error types, Result types, CError constants and so on.
  • The constants and types to export, including those defined directly with pub type and pub const, and those defined indirectly with pub use from other modules.
  • All the FFI functions to export.

The re-wrapped contents can be written in a separate module wrapper.rs. lib.rs only contains the error definitions, the types to export, the constants and the functions.

Dependency Specification

When adding sarasacw-omrf to the dependencies of the FFI project, we require specifying it as a git repository, supplemented with a tag and the version field, to ensure the version is correct. As shown below:

sarasacw-omrf = { version="1.0.0", git = "https://github.com/SarasasChipWorkshop/sarasacw-omrf.git", tag = "omrf/1.0.0" }