问题描述
我目前正在尝试使用c#中的Direct3D,并且已经开始使用D3D12GetDebugInterface API。 该函数的C ++语法如下(从Microsoft文档复制):
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接口添加接口Guid和InterfaceType属性。
- 可以使用
UnmanagedType.LPStruct
通过引用轻松传递向导。 - 您在这里不需要不安全的代码。
- 您应该检查错误(我的代码中未完成)
- 如果您需要DirectX的.NET接口定义,则可以在以下位置使用此开源项目:https://github.com/smourier/DirectN,例如:https://github.com/smourier/DirectN/blob/master/DirectN/DirectN/Generated/ID3D12Debug.cs