Reputation: 298
I am currently trying to use Direct3D from c# and I've started by using the D3D12GetDebugInterface API. The C++ syntax of the function is as follows (copied from the Microsoft documentation):
HRESULT D3D12GetDebugInterface(
REFIID riid,
void **ppvDebug
);
I'm having trouble importing the function into C#. I thought that maybe riid should be a pointer to a Guid struct, and I'm just using an IntPtr for **ppvDebug. Since **ppvDebug is a pointer to a pointer to an ID3D12Debug interface, I tried reimplementing the ID3D12Debug interface in C# code and using Marshal.PtrToStructure() to resolve the IntPtr to a usable ID3D12Debug interface instance, but that won't work. I remember reading about the ID3D12Debug interface being a COM object, but don't you need an ID for a COM object so you can import it? I haven't found any sort of COM ID anywhere in the documentation.
Anyway here's my latest attempt at getting something out of the function:
[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();
}
}
In case you want to see my ID3D12Debug interface:
interface ID3D12Debug
{
void EnableDebugLayer();
}
As I said, I think Direct3D makes use of COM, which I am completely missing here, so maybe that's why it doesn't work.
Upvotes: 1
Views: 400
Reputation: 138776
There are usually many ways to declare interop code. Here is one that should work:
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();
}
UnmanagedType.LPStruct
Upvotes: 3