Module interoptopus::patterns::api_guard[][src]

Expand description

Helper to ensure the bindings match the used DLL.

Using an API guard is as simple as defining and exporting a function my_api_guard returning an APIVersion as in the example below. Backends supporting API guards will automatically generate guard code executed when the library is loaded.

When developing we highly recommend adding API guards, as mismatching bindings are the #1 cause of “inexplicable” errors (undefined behavior) that often take hours to hunt down.

Example

This will create a FFI function called pattern_api_guard, and backends might automatically create guards calling this function when loading the DLL.

use interoptopus::ffi_function;
use interoptopus::patterns::api_guard::APIVersion;

// Inventory of our exports.
interoptopus::inventory!(
    my_inventory,
    [],
    [ my_api_guard ],
    [], []
);

// Guard function used by backends.
#[ffi_function]
#[no_mangle]
pub extern "C" fn my_api_guard() -> APIVersion {
    APIVersion::from_library(&my_inventory())
}

In backends that support API guards an error message like this might be emitted if you try load a library with mismatching bindings:

Exception: API reports hash X which differs from hash in bindings (Y). You probably forgot to update / copy either the bindings or the library.

Hash Value

The hash value

  • is based on the signatures of the involved functions, types and constants,
  • is expected to change when the API changes, e.g., functions, types, fields, … are added changed or removed,
  • will even react to benign API changes (e.g., just adding functions),
  • might even react to documentation changes (subject to change; feedback welcome).

Structs

Holds the API version hash of the given library.

Functions

Returns a unique hash for a library; used by backends.