Add a way to convert from an `Interface` to `Option<Interface>`
Some APIs like VSSetConstantBuffers take an *const Option<ID3D11Buffer>. Given a &ID3D11Buffer I'd like to be able to construct a &Option<ID3D11Buffer> to pass to a function like this.
Doing &buffer.clone().into() works fine for turning &ID3D11Buffer into &Option<ID3D11Buffer>
This API is difficult to use because it really expects an array but the Rust bindings aren't yet adapted to accept a slice.
This is a duplicate of #479 that I hope to get to soon.
Sorry for the delay, #1562 adds support for Win32 array parameters.
Unfortunately #1562 does not solve the core issue. Even for functions that take slices, they expect slices of &[Option<T>], which makes it difficult when you have a &[T]. The .clone().into() trick works well if you have a slice of size 1, but for slices without known size, we either have to map over the slices of T to Option<T>::Some, or transmute &[T] to &[Option<T>]
Reopening to address this.
This function is generated as follows:
pub unsafe fn VSSetConstantBuffers(&self, startslot: u32, ppconstantbuffers: &[::core::option::Option<ID3D11Buffer>]) {
(::windows::core::Interface::vtable(self).VSSetConstantBuffers)(::core::mem::transmute_copy(self), ::core::mem::transmute(startslot), ppconstantbuffers.len() as _, ::core::mem::transmute(::windows::core::as_ptr_or_null(ppconstantbuffers)))
}
This is in line with the metadata:
unsafe void VSSetConstantBuffers([In] uint StartSlot, [In] uint NumBuffers, [Optional][In][NativeArrayInfo(CountParamIndex = 1)] ID3D11Buffer* ppConstantBuffers);
Unfortunately, there's nothing in the metadata that says that the interface pointers in the array may not be null, hence the Option. Such a (non-null) option could be explored here: https://github.com/microsoft/win32metadata
What if an IntoParam<Option<T>> implementation is generated for every T that is exposed by a function as [In][Optional]? The issue here is that it's difficult to pass &[T] into functions that accept &[Option<T>], and likewise for the non-slice variants without transmute. This is a sound-ish transmute in the context of COM and COM-lite APIs but only because Rust guarantees so (kind of) for #[repr(transparent)], and because the input to the transmute is non-null, contract wise it is still wildly unsafe (if the wrapped COM ptr is null, the transmute is UB). Expressing it as IntoParam would codifying this relation in the function contract, but I'm not familiar enough to know if this is feasible codegen wise.
This wouldn't work for [Out] params for obvious reasons but for [In] params it would eliminate the need to use transmute here.
Ah that's a good point, thanks for the reminder! Yes, I'll experiment with using IntoParam for input arrays.