#[macro_export]
macro_rules! com_interface {
(
$(#[$iface_attr:meta])*
interface $iface:ident: $base_iface:ty {
iid: $iid:ident,
vtable: $vtable:ident,
$(
$(#[$fn_attr:meta])*
fn $func:ident($($i:ident: $t:ty),*) -> $rt:ty;
)*
}
) => (
#[allow(missing_debug_implementations)]
#[doc(hidden)]
#[repr(C)]
pub struct $vtable {
base: <$base_iface as $crate::ComInterface>::Vtable,
$($func: extern "stdcall" fn(*const $iface, $($t),*) -> $rt),*
}
$(#[$iface_attr])*
#[derive(Debug)]
#[repr(C)]
pub struct $iface {
vtable: *const $vtable
}
impl $iface {
$($(#[$fn_attr])*
pub unsafe fn $func(&self, $($i: $t),*) -> $rt {
((*self.vtable).$func)(self $(,$i)*)
})*
}
impl ::std::ops::Deref for $iface {
type Target = $base_iface;
fn deref(&self) -> &$base_iface {
unsafe { ::std::mem::transmute(self) }
}
}
unsafe impl $crate::AsComPtr<$iface> for $iface {}
unsafe impl $crate::AsComPtr<$base_iface> for $iface {}
unsafe impl $crate::ComInterface for $iface {
#[doc(hidden)]
type Vtable = $vtable;
#[allow(unused_unsafe)]
fn iid() -> $crate::IID { unsafe { $iid } }
}
);
(
$(#[$iface_attr:meta])*
interface $iface:ident: $base_iface:ty, $($extra_base:ty),+ {
iid: $iid:ident,
vtable: $vtable:ident,
$(
$(#[$fn_attr:meta])*
fn $func:ident($($i:ident: $t:ty),*) -> $rt:ty;
)*
}
) => (
com_interface! {
$(#[$iface_attr])*
interface $iface: $base_iface {
iid: $iid,
vtable: $vtable,
$($(#[$fn_attr])* fn $func($($i: $t),*) -> $rt;)*
}
}
$(unsafe impl $crate::AsComPtr<$extra_base> for $iface {})*
)
}
#[macro_export]
macro_rules! iid {
($(#[$iid_attr:meta])*
$name:ident = $d1:expr, $d2:expr, $d3:expr, $($d4:expr),*) => (
$(#[$iid_attr])*
const $name: $crate::IID = $crate::IID {
data1: $d1,
data2: $d2,
data3: $d3,
data4: [$($d4),*],
};
);
($(#[$iid_attr:meta])*
pub $name:ident = $d1:expr, $d2:expr, $d3:expr, $($d4:expr),*) => (
$(#[$iid_attr])*
pub const $name: $crate::IID = $crate::IID {
data1: $d1,
data2: $d2,
data3: $d3,
data4: [$($d4),*],
};
);
}