Skip to content

Better Interop Support for Unmanaged Interfaces #6413

@tannergooding

Description

@tannergooding

Issue:
There is currently support for four interface types:

  • Dual (IDispatch and VTBL exposure with IUnknown implicitly as the first set of entries)
  • IDispatch
  • IInspectable (Windows Runtime)
  • IUnknown (VTBL exposure with IUnknown implicitly as the first set of entries)

This makes it difficult to support interfaces which does not inherit from IUnknown (such as ID3D12FunctionReflection) that are returned from another COM Object that does inherit from IUnknown (such as ID3D12LibraryReflection).

Workaround:
In order to support these objects, one must manually implement a structure that wraps a VTBL, such as:

struct ID3D12FunctionParameterReflection
{
    public Vtbl* lpVtbl;        // or: public IntPtr lpVtbl;

    public struct Vtbl
    {
        public IntPtr GetDesc;  // or: public _GetDesc GetDesc;
    }

    public delegate int _GetDesc(ref ID3D12FunctionParameterReflection @this, out D3D12_PARAMETER_DESC pDesc);
}

Doing this can be error prone and requires a lot of manual coding to get the interop working correctly as you have to either Marshal the Vtbl (using PtrToStructure) or Marshal the individual method pointers (using GetDelegateForFunctionPointer) and you must explicitly pass the this parameter to all method calls.

Request:
We should support a fifth interface type:

  • Native (VTBL exposure, where IUnknown is not the first set of entries)

Constructing such an interface would then look like:

[InterfaceType(ComInterfaceType.Native)]
public interface ID3D12FunctionParameterReflection
{
    [PreserveSig]
    int GetDesc(
        [Out] out D3D12_PARAMETER_DESC pDesc
    );
}

The above is much simpler, easier to read/follow. However, given that it does not inherit from IUnknown, its lifetime must be explicitly managed (this was already the case with the workaround listed above).

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions