This module defines invocation_handler attribute procedural macro. It allows simplifiing of
principal module invocation handler signature. According to Fluence Wasm backend convensions
is can look like this:
#[no_mangle]
pub unsafe fn invoke(ptr: *mut u8, len: usize) -> NonNull<u8> {
let user_name = fluence::memory::read_input_from_mem(ptr, len);
let user_name: String = String::from_utf8(user_name).unwrap();
// return a pointer to the result in memory
fluence::memory::write_result_to_mem(format!("Hello from Fluence to {}", user_name).as_bytes())
.expect("Putting result string to the memory was failed.")
}
Instead of this you can write more pretty one using #[invocation_handler]:
use fluence::sdk::*;
#[invocation_handler]
fn main(name: String) -> String {
format!("Hello from Fluence to {}", name)
}
To use this macro with some function f
some conditions have to be met:
f
has to have one input argument.f
has to don't beunsafe
,const
, generic or have custom abi linkage or variadic param.- The input and output types of
f
has to be in {String, Vec} set. f
has to don't have nameinvoke
.
For trubleshooting and macros debugging carga expand can be used.
Internally this macros creates a new function invoke
that converts a raw argument to
appropriate format, call f
and then converts its result by memory::write_result_to_mem
from
fluence_sdk_main
. So to use this crate apart from fluence
at first fluence_sdk_main
has
to be imported.
Safety
Nothing special: f
recevies an argument and returns a result by value.
Examples
Please find more examples in https://github.com/fluencelabs/fluence/tree/master/vm/examples
.