จะใช้ D3D12GetDebugInterface API จาก c # ได้อย่างไร
ฉันกำลังพยายามใช้ Direct3D จาก c # และฉันได้เริ่มต้นโดยใช้ D3D12GetDebugInterface API ไวยากรณ์ C ++ ของฟังก์ชันมีดังต่อไปนี้ (คัดลอกจากเอกสารของ Microsoft):
HRESULT D3D12GetDebugInterface(
REFIID riid,
void **ppvDebug
);
ฉันมีปัญหาในการนำเข้าฟังก์ชันไปยัง C # ฉันคิดว่า riid น่าจะเป็นตัวชี้ไปยัง Guid struct และฉันแค่ใช้ IntPtr สำหรับ ** ppvDebug เนื่องจาก ** ppvDebug เป็นตัวชี้ไปยังตัวชี้ไปยังอินเทอร์เฟซ ID3D12Debug ฉันจึงลองใช้อินเทอร์เฟซ ID3D12Debug ใหม่ในโค้ด C # และใช้ Marshal.PtrToStructure () เพื่อแก้ไข IntPtr เป็นอินสแตนซ์อินเทอร์เฟซ ID3D12Debug ที่ใช้งานได้ แต่จะไม่ได้ผล ฉันจำได้ว่าอ่านเกี่ยวกับอินเทอร์เฟซ ID3D12Debug เป็นวัตถุ COM แต่คุณไม่ต้องการ ID สำหรับวัตถุ COM เพื่อให้คุณสามารถนำเข้าได้หรือไม่ ฉันไม่พบ 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();
}
- คุณต้องเพิ่มแอตทริบิวต์ของอินเตอร์เฟส Guid และ InterfaceType สำหรับอินเตอร์เฟส COM
- Guid สามารถส่งผ่านได้อย่างง่ายดายโดยใช้การอ้างอิง
UnmanagedType.LPStruct - คุณไม่จำเป็นต้องใช้รหัสที่ไม่ปลอดภัยที่นี่
- คุณควรตรวจสอบข้อผิดพลาด (ยกเลิกในรหัสของฉัน)
- หากคุณต้องการนิยามอินเตอร์เฟส. NET กับ DirectX คุณสามารถใช้โปรเจ็กต์โอเพนซอร์สนี้ได้ที่นี่: https://github.com/smourier/DirectN, ตัวอย่างเช่น: https://github.com/smourier/DirectN/blob/master/DirectN/DirectN/Generated/ID3D12Debug.cs