`windows-rdl` non-COM interfaces do not support inheritance
Author: DrChatCreated Jan 13, 2023Updated Jul 7, 2026
Labelsenhancement
A familiar foe returns: I'm trying to create a compatibility library that binds XAudio 2.7 to XAudio 2.9 for a legacy game.
However, I can't declare a few APIs using the #[interface] macro since they derive from IXAudio2Voice, which isn't a COM interface.
This is related to #2098 (and other issues/PRs related to that).
For a minimum repro, use the following test (which was modified from non_com_new.rs):
#![allow(non_snake_case, non_camel_case_types)]
use windows::core::*;
// The `interface` macro defines a new local interface that does not derive from `IUnknown` and thus is not a COM interface at all.
#[interface]
unsafe trait IBase {
unsafe fn BaseValue(&self) -> i32;
}
#[interface]
unsafe trait IDerived: IBase {
unsafe fn DerivedValue(&self) -> i32;
}
struct Base(i32);
impl IBase_Impl for Base {
unsafe fn BaseValue(&self) -> i32 {
self.0
}
}
struct Derived(i32, i32);
impl IBase_Impl for Derived {
unsafe fn BaseValue(&self) -> i32 {
self.0
}
}
impl IDerived_Impl for Derived {
unsafe fn DerivedValue(&self) -> i32 {
self.1
}
}
unsafe fn base_value(test: &IBase) -> i32 {
test.BaseValue()
}
unsafe fn derived_value(test: &IDerived) -> i32 {
test.DerivedValue()
}
#[test]
fn base() {
unsafe {
// Since the interface is not rooted in `IUnknown`, there's no COM-style lifetime and the resulting implementation merely
// exists for the lifetime of the referenced implementation.
let test = Base(456);
let interface = IBase::new(&test);
assert_eq!(base_value(&interface), 456);
assert_eq!(interface.BaseValue(), 456);
}
}
#[test]
fn derived() {
unsafe {
let test = Derived(123, 456);
let interface = IDerived::new(&test);
assert_eq!(base_value(&interface), 123);
assert_eq!(interface.BaseValue(), 123);
assert_eq!(derived_value(&interface), 456);
assert_eq!(interface.DerivedValue(), 456);
}
}Specifically, this is the error thrown:
error[E0107]: this associated function takes 1 generic argument but 3 generic arguments were supplied
--> crates\tests\interface\tests\non_com_new.rs:11:1
|
11 | #[interface]
| ^^^^^^^^^^^^
| |
| expected 1 generic argument
| help: remove these generic arguments
|Cc @kennykerr (you seem to be the one most familiar with this class of issues)
Source: microsoft/windows-rs