如何从 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();
}
- 您必须为 COM 接口添加 interface Guid 和 InterfaceType 属性。
- 可以使用
UnmanagedType.LPStruct
通过引用轻松传递 Guid
- 这里不需要不安全的代码。
- 您应该检查错误(在我的代码中未完成)
- 如果您需要使用 DirectX 的 .NET 接口定义,您可以在这里使用这个开源项目:https://github.com/smourier/DirectN, for example: https://github.com/smourier/DirectN/blob/master/DirectN/DirectN/Generated/ID3D12Debug.cs
我目前正在尝试通过 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();
}
- 您必须为 COM 接口添加 interface Guid 和 InterfaceType 属性。
- 可以使用
UnmanagedType.LPStruct
通过引用轻松传递 Guid
- 这里不需要不安全的代码。
- 您应该检查错误(在我的代码中未完成)
- 如果您需要使用 DirectX 的 .NET 接口定义,您可以在这里使用这个开源项目:https://github.com/smourier/DirectN, for example: https://github.com/smourier/DirectN/blob/master/DirectN/DirectN/Generated/ID3D12Debug.cs