microsoft/windows-rs

Guidance for dealing with callbacks

Closed this issue · 5 comments

Suggestion

The windows::Windows::Win32::Graphics::Direct3D::Fxc::D3DCompile API call supports providing an implementation of the ID3DInclude interface, so that application developers can provide custom callbacks to handle #include file handling.

In C++ this works by creating a class and deriving it from ID3DInclude, like so:

class MyCustomInclude : public ID3DInclude
{
    HRESULT Open(D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID* ppData, UINT* pBytes) override
    {
        // ...get some bytes based on input parameters...
    }

    HRESULT Close(LPCVOID pData) override
    {
        // ...free buffers, etc...
    }
};

It's unclear to me how this needs to be handled in windows-rs, though. ID3DInclude is not modelled as a trait I can implement, so my next thought was to manually fill the ID3DInclude_Vtbl with Open and Close function pointers. However, it's unclear to me how to take that vtable, construct a new ID3DInclude from that and provide it to D3DCompile.

It would be nice if there would be a snippet of documentation or a sample showing how to deal with these interface implementations, but I'm not sure how often that comes up in other areas of the Windows APIs.

You may be missing the "implement" feature in the latest release. This requirement has since been removed (#3333) which should make this easier to discover in future.

[dependencies.windows]
version = "0.58"
features = [
    "implement",
    "Win32_Graphics_Direct3D",
]
use std::ffi::c_void;
use windows::{core::*, Win32::Graphics::Direct3D::*};

struct Include;

impl ID3DInclude_Impl for Include {
    fn Open(
        &self,
        _: D3D_INCLUDE_TYPE,
        _: &PCSTR,
        _: *const c_void,
        _: *mut *mut c_void,
        _: *mut u32,
    ) -> Result<()> {
        todo!()
    }
    fn Close(&self, _: *const c_void) -> Result<()> {
        todo!()
    }
}

fn main() {
    let _include = ID3DInclude::new(&Include);
}

I did indeed miss that, thanks!

Sorry to reopen this, but there is currently a caveat: the new method of ID3DInclude is behind a std feature gate, which doesn't seem needed afaict. It does create a Box so it does need extern crate alloc, as well. Can this feature gate be removed? It does seem to run fine without this gate.

That also explains why I missed it, since I'm building with no-std.

Yes, I'm planning to fix that: #3335

Wow, thanks for all the hard work, it's very much appreciated.