Attribute Macro interoptopus::ffi_service_method[][src]

#[ffi_service_method]
This is supported on crate feature derive only.
Expand description

Inside a #[ffi_service] block, provide special directives to functions.

This is an optional attribute that can be applied to some methods.

By default service methods must return a Result<(), Error> return type that will be mapped to an FFIError and transparently checked in languages supporting the pattern. However, sometimes you might want to return an actual value. Using this attribute you can opt out of error mapping and instead return the value as-is.

See the service module for an introduction into services.

Parameters

The following attributes can be provided:

ParameterExplanation
wrapDetermines the wrapping behavior of the generated C method (result, direct, raw), see below.

Wrapping Behavior

Details what wrap means:

ModeExplanation
resultExpects method to return Result<(), Error> and maps that to an FFIError. Default behavior.
directMethod can return any value. If panic occurred Default::default() will be returned, see below.
rawMethod can return any value. If panic occurs undefined behavior happens. Mostly an escape hatch when running into lifetime issues in autogenerated code (e.g., when returning an AsciiPointer from a service). In the long term our proc macro code gen should be fixed to handle this situation.

Panic Behavior

⚠️ Generated methods add panic guards when used with result and direct. However, since direct methods have no other way to signal errors they will return Default::default() instead if a panic is encountered. If you compiled Interoptopus with the log feature a message will be emitted in that case.

Example

use interoptopus::{ffi_type, ffi_service, ffi_service_ctor, ffi_service_method};

#[ffi_type(opaque)]
pub struct SimpleService { }

#[ffi_service(error = "MyFFIError", prefix = "simple_service_")]
impl SimpleService {

    #[ffi_service_ctor]
    pub fn new_with(some_value: u32) -> Result<Self, Error> {
        Ok(Self { })
    }

    #[ffi_service_method(wrap = "direct")]
    pub fn return_value(&self) -> u32 {
        123
    }

    #[ffi_service_method(wrap = "direct")]
    #[allow(unconditional_panic)]
    pub fn oops(&self, x: u32) -> u32 {
        let array = [0, 1, 2];

        // This will panic. The method will return 0 instead.
        array[5]
    }
}