Skip to content

Instantly share code, notes, and snippets.

@kennykerr
Last active May 21, 2024 15:14
Show Gist options
  • Save kennykerr/914cc9d577f15add47047cdb13553184 to your computer and use it in GitHub Desktop.
Save kennykerr/914cc9d577f15add47047cdb13553184 to your computer and use it in GitHub Desktop.
use windows_core::*;
#[interface("1bd72b4b-8d05-44c6-8909-da3e0e91afa0")]
unsafe trait IDebug: IUnknown {
fn debug_carrot(&self, carrot: Ref<ICarrot>) -> Result<()>;
fn debug_pear(&self, pear: Ref<IPear>) -> Result<()>;
}
#[interface("3bde3f9e-4d7c-4d5f-8322-4b226e0e1b91")]
unsafe trait ICarrot: IUnknown {
fn eat(&self) -> i32;
fn debug(&self, debug: Ref<IDebug>) -> Result<()>;
}
#[interface("a0c5f98a-ddce-49df-9ac9-08c597a9c518")]
unsafe trait IPear: IUnknown {
fn eat(&self) -> i32;
fn debug(&self, debug: Ref<IDebug>) -> Result<()>;
}
#[implement(ICarrot, IPear, IDebug)]
struct Confused(i32);
impl IDebug_Impl for Confused {
unsafe fn debug_carrot(&self, carrot: Ref<ICarrot>) -> Result<()> {
println!(" IDebug::debug_carrot: {}", carrot.ok()?.eat());
Ok(())
}
unsafe fn debug_pear(&self, pear: Ref<IPear>) -> Result<()> {
println!(" IDebug::debug_pear: {}", pear.ok()?.eat());
Ok(())
}
}
impl ICarrot_Impl for Confused {
unsafe fn eat(&self) -> i32 {
self.0 * 10
}
unsafe fn debug(&self, debug: Ref<IDebug>) -> Result<()> {
println!("ICarrot::debug {}", self.0);
let debug = debug.ok()?;
debug.debug_carrot(self)?;
debug.debug_pear(self)?;
Ok(())
}
}
impl IPear_Impl for Confused {
unsafe fn eat(&self) -> i32 {
self.0 * 100
}
unsafe fn debug(&self, debug: Ref<IDebug>) -> Result<()> {
println!("IPear::debug {}", self.0);
let debug = debug.ok()?;
debug.debug_carrot(self)?;
debug.debug_pear(self)?;
Ok(())
}
}
fn main() -> Result<()> {
unsafe {
let debug: IDebug = Confused(123).into();
let carrot: ICarrot = debug.cast()?;
let pear: IPear = carrot.cast()?;
assert_eq!(carrot.eat(), 123 * 10);
assert_eq!(pear.eat(), 123 * 100);
carrot.debug(&debug)?;
pear.debug(&debug)?;
Ok(())
}
}
// TODO: the `implement` macro must generate these:
impl Param<ICarrot, InterfaceType> for &Confused {
unsafe fn param(self) -> ParamValue<ICarrot> {
// TODO: this should be ParamValue::Borrowed and avoid QI
ParamValue::Owned(self.cast().unwrap())
}
}
impl Param<IPear, InterfaceType> for &Confused {
unsafe fn param(self) -> ParamValue<IPear> {
// TODO: this should be ParamValue::Borrowed and avoid QI
ParamValue::Owned(self.cast().unwrap())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment