com_rs

Macro com_interface

Source
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.