microsoft / windows-rs

Rust for Windows
https://kennykerr.ca/rust-getting-started/
Apache License 2.0
10.35k stars 486 forks source link

windows-bindgen: functions not generated from winmd after upgrade to 0.57 #3100

Closed youyuanwu closed 3 months ago

youyuanwu commented 3 months ago

Summary

After upgrading to version 0.57, functions previously marked with feature "Win32_Foundation" no longer exists. The function refers to the type windows::Win32::Foundation::BOOLEAN.

See: https://github.com/Azure/service-fabric-rs/issues/38 for example.

Crate manifest

No response

Crate code

No response

kennykerr commented 3 months ago

This is likely related to https://github.com/microsoft/windows-rs/pull/2735 and is by design.

youyuanwu commented 3 months ago

@kennykerr This does not happen for 0.56 but only in 0.57. Seems to be not caused from the commit you mentioned.

This caused those functions not generated and not accessible. I want to use those functions, how to make windows-bindgen generate them? Is there a new flag in 0.57 to enable Win32_Foundation?

kennykerr commented 3 months ago

Taking this winmd file: https://github.com/Azure/service-fabric-metadata/blob/main/.windows/winmd/Microsoft.ServiceFabric.winmd

I see the definition for IFabricAsyncOperationContext includes these four methods:

[Guid(2216108223u, 51688, 20079, 156, 63, 107, 127, 74, 199, 59, 205)]
[Agile]
public interface IFabricAsyncOperationContext : IUnknown
{
    BOOLEAN IsCompleted();

    BOOLEAN CompletedSynchronously();

    [SpecialName]
    unsafe HRESULT get_Callback([Out][RetVal] IFabricAsyncOperationCallback* callback);

    HRESULT Cancel();
}

And running this command:

[dependencies.windows-bindgen]
version = "0.57"
fn main() {
    windows_bindgen::bindgen([
        "--in",
        "/git/Microsoft.ServiceFabric.winmd",
        "--out",
        "src/bindings.rs",
        "--filter",
        "Microsoft",
        "--config",
        "implement",
    ])
    .unwrap();
}

This generates bindings that includes:

impl IFabricAsyncOperationContext {
    pub unsafe fn IsCompleted(&self) -> windows::Win32::Foundation::BOOLEAN {
        (windows_core::Interface::vtable(self).IsCompleted)(
            windows_core::Interface::as_raw(self),
        )
    }
    pub unsafe fn CompletedSynchronously(&self) -> windows::Win32::Foundation::BOOLEAN {
        (windows_core::Interface::vtable(self).CompletedSynchronously)(
            windows_core::Interface::as_raw(self),
        )
    }
    pub unsafe fn Callback(&self) -> windows_core::Result<IFabricAsyncOperationCallback> {
        let mut result__ = core::mem::zeroed();
        (windows_core::Interface::vtable(self).Callback)(
            windows_core::Interface::as_raw(self),
            &mut result__,
        )
        .and_then(|| windows_core::Type::from_abi(result__))
    }
    pub unsafe fn Cancel(&self) -> windows_core::Result<()> {
        (windows_core::Interface::vtable(self).Cancel)(windows_core::Interface::as_raw(
            self,
        ))
        .ok()
    }
}

Compiling the bindings with the following dependencies seems to work fine:

[dependencies.windows]
version = "0.57"
features = [
    "Win32_Foundation",
]

[dependencies.windows-core]
version = "0.57"

In future, please include a repro of this sort. That being said, what's missing?

youyuanwu commented 3 months ago

Bindgen config=implement generates correct functions. But I am using this:

--in  ./windows/Microsoft.ServiceFabric.winmd
--out crates/libs/com/src/Microsoft.rs

--filter
    Microsoft

--config
  package=true

package=true generates the code with functions missing in this issue.

kennykerr commented 3 months ago

Ah, the package config option is only meant for the windows and windows-sys crates. If you use the options I suggested above then you'll get all the bindings just in a single source file. It's a lot simpler. The package config option is really just meant to deal with the vast size of the Windows API and as such has a few really peculiar characteristics that don't apply to other crates.