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; )* } ) => { ... }; ( $(#[$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; )* } ) => { ... }; }
Expand description
Macro for generating COM interface definitions.
§Usage
#[macro_use]
extern crate com_rs;
use com_rs::IUnknown;
iid!(IID_IFOO =
0x12345678, 0x90AB, 0xCDEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF);
com_interface! {
interface IFoo: IUnknown {
iid: IID_IFOO,
vtable: IFooVtbl,
fn foo() -> bool;
}
}
This example defines an interface called IFoo
. In this case, the base type is
IUnknown, the root COM type. The IID for the interface must also be defined,
along with the name of the vtable type, IFooVtbl
. This isn’t publicly exposed,
but there is currently no way to generate an ident within a macro so the callee
must define one instead.
The trait Foo
defines the methods available for the interface, in this case
a single method named foo
. Note that any methods that return no value
(e.g. the void
type in C/C++) should return the unit type ()
.
§Inheritance
To define interfaces with a deeper hierarchy, add additional parent identifiers to the type definitions. e.g:
iid!(IID_IBAR =
0x12345678, 0x90AB, 0xCDEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF);
com_interface! {
interface IBar: IFoo, IUnknown {
iid: IID_IBAR,
vtable: IBarVtbl,
fn bar(baz: i32) -> ();
}
}
This example defines an interface called IBar
which extends IFoo
from the
previous example. Note that it is necessary to specify the parent types
for both the interface and trait declarations.
The interface hierarchy automates pointer conversion using the AsComPtr
trait,
and the trait hierarchy automatically implements the parent methods for the
child interface.