Comment utiliser l'API D3D12GetDebugInterface à partir de c #?
J'essaie actuellement d'utiliser Direct3D à partir de c # et j'ai commencé à utiliser l'API D3D12GetDebugInterface. La syntaxe C ++ de la fonction est la suivante (copiée à partir de la documentation Microsoft):
HRESULT D3D12GetDebugInterface(
REFIID riid,
void **ppvDebug
);
J'ai du mal à importer la fonction dans C #. J'ai pensé que peut-être riid devrait être un pointeur vers une structure Guid, et j'utilise juste un IntPtr pour ** ppvDebug. Puisque ** ppvDebug est un pointeur vers un pointeur vers une interface ID3D12Debug, j'ai essayé de réimplémenter l'interface ID3D12Debug en code C # et d'utiliser Marshal.PtrToStructure () pour résoudre l'IntPtr en une instance d'interface ID3D12Debug utilisable, mais cela ne fonctionnera pas. Je me souviens avoir lu que l'interface ID3D12Debug était un objet COM, mais n'avez-vous pas besoin d'un ID pour un objet COM pour pouvoir l'importer? Je n'ai trouvé aucune sorte d'identifiant COM dans la documentation.
Quoi qu'il en soit, voici ma dernière tentative pour obtenir quelque chose de la fonction:
[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();
}
}
Au cas où vous voudriez voir mon interface ID3D12Debug:
interface ID3D12Debug
{
void EnableDebugLayer();
}
Comme je l'ai dit, je pense que Direct3D utilise COM, ce qui me manque complètement ici, alors c'est peut-être pourquoi cela ne fonctionne pas.
Réponses
Il existe généralement de nombreuses façons de déclarer le code d'interopérabilité. En voici un qui devrait fonctionner:
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();
}
- Vous devez ajouter les attributs d'interface Guid et InterfaceType pour les interfaces COM.
- Guid peut être transmis facilement par référence en utilisant
UnmanagedType.LPStruct - Vous n'avez pas besoin de code dangereux ici.
- Vous devriez vérifier les erreurs (annulées dans mon code)
- Si vous avez besoin de définitions d'interface .NET avec DirectX, vous pouvez utiliser ce projet open source ici: https://github.com/smourier/DirectN, par example: https://github.com/smourier/DirectN/blob/master/DirectN/DirectN/Generated/ID3D12Debug.cs