interoptopus/patterns/api_entry.rs
1//! Helpers for API loading patterns as [described in this blog post](https://anteru.net/blog/2016/designing-c-apis-in-2016/).<sup>🚧</sup>
2//!
3//! See the macro [api_entry](crate::api_entry) for details.
4
5/// Defines a new API entry function and corresponding struct.
6///
7/// The resulting function can be called via FFI and will return a struct, pointing to all exported functions.
8///
9/// # Example
10///
11/// In this example, other languages can call `my_api_init_v1` to obtain a struct of type `MyAPIv1`
12/// exporting `f1` and `f2`.
13///
14/// ```rust
15/// use interoptopus::{api_entry, ffi_function};
16///
17/// #[ffi_function]
18/// extern "C" fn f1() {}
19///
20/// #[ffi_function]
21/// extern "C" fn f2() {}
22///
23/// api_entry!(MyAPIv1, my_api_init_v1, [f1, f2]);
24/// ```
25#[doc(hidden)]
26#[macro_export]
27macro_rules! api_entry {
28 (
29 $struct:ident,
30 $init:ident,
31 [
32 $($function:ident),*
33 ]
34 ) => {
35 pub struct $struct {
36 $($function: <$function as interoptopus::lang::rust::FunctionInfo>::Signature,)*
37 }
38
39 #[interoptopus::ffi_function]
40 #[no_mangle]
41 pub unsafe extern "C" fn $init(api: *mut $struct) {
42 if api.is_null() {
43 return;
44 }
45
46 let s = $struct {
47 $(
48 $function: $function,
49 )*
50 };
51
52 unsafe { *api = s; }
53 }
54
55
56 unsafe impl interoptopus::lang::rust::CTypeInfo for $struct {
57 fn type_info() -> interoptopus::lang::c::CType {
58 let mut fields = Vec::new();
59
60 $(
61 {
62 use interoptopus::lang::rust::FunctionInfo;
63 use $function as x;
64 let function: interoptopus::lang::c::Function = x::function_info();
65 let t = interoptopus::lang::c::CType::FnPointer(interoptopus::lang::c::FnPointerType::new(function.signature().clone()));
66 let field = interoptopus::lang::c::Field::new(function.name().to_string(), t);
67 fields.push(field);
68 }
69 )*
70
71 let composite = interoptopus::lang::c::CompositeType::new(stringify!($struct).to_string(), fields);
72 interoptopus::lang::c::CType::Composite(composite)
73 }
74 }
75 };
76}