¿Cómo utilizar la API D3D12GetDebugInterface desde c #?
Actualmente estoy tratando de usar Direct3D desde c # y comencé usando la API D3D12GetDebugInterface. La sintaxis de C ++ de la función es la siguiente (copiada de la documentación de Microsoft):
HRESULT D3D12GetDebugInterface(
REFIID riid,
void **ppvDebug
);
Tengo problemas para importar la función a C #. Pensé que tal vez riid debería ser un puntero a una estructura Guid, y solo estoy usando un IntPtr para ** ppvDebug. Dado que ** ppvDebug es un puntero a un puntero a una interfaz ID3D12Debug, intenté volver a implementar la interfaz ID3D12Debug en el código C # y usar Marshal.PtrToStructure () para resolver el IntPtr en una instancia de interfaz ID3D12Debug utilizable, pero eso no funcionará. Recuerdo haber leído que la interfaz ID3D12Debug es un objeto COM, pero ¿no necesitas una ID para un objeto COM para poder importarlo? No he encontrado ningún tipo de ID COM en ninguna parte de la documentación.
De todos modos, aquí está mi último intento de sacar algo de la función:
[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();
}
}
En caso de que quiera ver mi interfaz ID3D12Debug:
interface ID3D12Debug
{
void EnableDebugLayer();
}
Como dije, creo que Direct3D hace uso de COM, que me falta por completo aquí, así que tal vez por eso no funciona.
Respuestas
Por lo general, hay muchas formas de declarar código de interoperabilidad. Aquí hay uno que debería funcionar:
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();
}
- Debe agregar los atributos de interfaz Guid y InterfaceType para las interfaces COM.
- Guid se puede pasar fácilmente por referencia usando
UnmanagedType.LPStruct - No necesita un código inseguro aquí.
- Deberías comprobar si hay errores (deshecho en mi código)
- Si necesita definiciones de interfaz .NET con DirectX, puede usar este proyecto de código abierto aquí: https://github.com/smourier/DirectN, por ejemplo: https://github.com/smourier/DirectN/blob/master/DirectN/DirectN/Generated/ID3D12Debug.cs