如何从 C# 使用 D3D12GetDebugInterface API?

How to use D3D12GetDebugInterface API from c#?

我目前正在尝试通过 C# 使用 Direct3D,并且我已经开始使用 D3D12GetDebugInterface API。 该函数的C++语法如下(抄自微软文档):

HRESULT D3D12GetDebugInterface(
    REFIID riid,
    void   **ppvDebug
);

我在将函数导入 C# 时遇到问题。我想也许 riid 应该是一个指向 Guid 结构的指针,而我只是将 IntPtr 用于 **ppvDebug。由于 **ppvDebug 是指向 ID3D12Debug 接口的指针,我尝试在 C# 代码中重新实现 ID3D12Debug 接口并使用 Marshal.PtrToStructure() 将 IntPtr 解析为可用的 ID3D12Debug 接口实例,但这不起作用.我记得读过有关 ID3D12Debug 接口是一个 COM 对象的信息,但是您不需要 COM 对象的 ID 以便导入它吗?我在文档中的任何地方都没有找到任何类型的 COM ID。

无论如何,这是我最近尝试从函数中获取一些东西的尝试:

[DllImport("D3D12.dll")]
static extern int D3D12GetDebugInterface(IntPtr riid, IntPtr ppvDebug);

void func() {
    unsafe
    {
        IntPtr DebugControllerPtr = IntPtr.Zero;

        Type InterfaceType = typeof(ID3D12Debug);
        Guid ID = InterfaceType.GUID;
        IntPtr ptr = Marshal.AllocHGlobal(sizeof(Guid));
        Marshal.StructureToPtr(ID, ptr, false);

        D3D12GetDebugInterface(ptr, DebugControllerPtr);
        Marshal.FreeHGlobal(ptr);
        ID3D12Debug DebugController = null;
        Marshal.PtrToStructure(DebugControllerPtr, DebugController);
        DebugController.EnableDebugLayer();
    }
}

如果你想看我的ID3D12Debug界面:

interface ID3D12Debug
{
    void EnableDebugLayer();
}

正如我所说,我认为 Direct3D 使用了 COM,而我在这里完全没有看到它,所以也许这就是它不起作用的原因。

声明互操作代码的方式通常有很多种。这是一个应该有效的方法:

public static void Main()
{
    D3D12GetDebugInterface(typeof(ID3D12Debug).GUID, out var obj);
    var debug = (ID3D12Debug)obj;
    debug.EnableDebugLayer(); // for example
}

[DllImport("D3D12")]
public static extern int D3D12GetDebugInterface([MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppvDebug);

[Guid("344488b7-6846-474b-b989-f027448245e0"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ID3D12Debug
{
    [PreserveSig]
    void EnableDebugLayer();
}