Core COM and WinRT type support shared by the windows-* crates.
- π¦ crates.io
- π docs.rs
- π Getting started
- π Source
windows-core is the foundation that nearly every other crate builds on. It
provides the COM/WinRT runtime machinery β IUnknown, IInspectable, the
Interface trait, reference counting, agile references, and weak references β
along with GUID and re-exports of the result and
string types.
It is also where you declare and implement your own COM and WinRT interfaces.
The #[interface] and #[implement] macros live in the separate
windows-interface and
windows-implement crates only because Rust requires
procedural macros to ship in their own proc-macro crate. They are part of
windows-core β re-exported from it behind the default proc-macros feature and
documented here rather than as standalone crates.
Declare a COM interface as an unsafe trait deriving from IUnknown with
#[interface] and its GUID, then provide a Rust type for it with #[implement]:
use windows_core::*;
#[interface("7e75ffe0-2f8c-4040-953e-b1f83a48f77b")]
unsafe trait IValue: IUnknown {
unsafe fn value(&self) -> i32;
}
#[implement(IValue)]
struct Value {
value: i32,
}
impl IValue_Impl for Value_Impl {
unsafe fn value(&self) -> i32 {
self.value
}
}
fn main() {
let object: IValue = Value { value: 42 }.into();
assert_eq!(unsafe { object.value() }, 42);
// COM identity: `cast` queries for another interface on the same object.
let unknown: IUnknown = object.cast().unwrap();
let again: IValue = unknown.cast().unwrap();
assert_eq!(unsafe { again.value() }, 42);
}#[interface] generates the vtable, the safe caller-side wrappers, and the
IValue_Impl trait. #[implement] generates the Value_Impl wrapper that carries
the vtable pointers and reference count; you write the methods in
impl IValue_Impl for Value_Impl. Converting the struct .into() an interface
yields a reference-counted COM object, and cast moves between interfaces on the
same object.
Disabling the default proc-macros feature drops the syn/quote/proc-macro2
build dependencies. The interface_decl! and implement_decl! declarative
macro_rules! macros then cover the common case β an always-agile type
implementing one or more IUnknown-derived interfaces β without proc macros. They
are more verbose (every identifier and the IID must be spelled out) and narrower in
scope; see the interface_macro and implement_macro module docs for the grammar
and limits. windows-core uses them internally so it can build with proc-macros
disabled.
The remainder of this page covers how the crate is built and maintained. It is
for contributors and is not needed to use windows-core.
src/bindings.rs is generated by tool_bindings from
crates/tools/bindings/src/core.txt. The hand-written modules
(agile_reference, com_object, compose, event, β¦) provide the COM runtime
support. The #[implement]/#[interface] proc macros are re-exported from the
windows-implement/windows-interface
crates behind the proc-macros feature, and the implement_macro/interface_macro
modules supply the implement_decl!/interface_decl! declarative equivalents used
when that feature is off.
Run cargo test -p windows-core; see also the workspace test crates.