C # से D3D12GetDebugInterface API का उपयोग कैसे करें?

Sep 16 2020

मैं वर्तमान में सी # से Direct3D का उपयोग करने की कोशिश कर रहा हूं और मैंने D3D12GetDebugInterface API का उपयोग करके शुरू किया है। फ़ंक्शन का C ++ सिंटैक्स निम्नानुसार है (Microsoft दस्तावेज़ से कॉपी किया गया):

HRESULT D3D12GetDebugInterface(
    REFIID riid,
    void   **ppvDebug
);

मुझे फ़ंक्शन को C # में आयात करने में समस्या हो रही है। मुझे लगा कि शायद ridid ​​एक गाइड स्ट्रक्चर का पॉइंटर होना चाहिए, और मैं ** ppvDugug के लिए एक IntPtr का उपयोग कर रहा हूं। चूँकि ** 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 का उपयोग करता है, जिसे मैं यहां पूरी तरह से याद कर रहा हूं, इसलिए शायद यह काम नहीं करता है।

जवाब

1 SimonMourier Sep 16 2020 at 20:41

इंटरोप कोड घोषित करने के कई तरीके हैं। यहाँ एक है जो काम करना चाहिए:

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 इंटरफ़ेस के लिए इंटरफ़ेस गाइड और InterfaceType विशेषताओं को जोड़ना होगा।
  • गाइड का उपयोग करके संदर्भ आसानी से पारित किया जा सकता है UnmanagedType.LPStruct
  • आपको यहां असुरक्षित कोड की आवश्यकता नहीं है।
  • आपको त्रुटियों की जांच करनी चाहिए (मेरे कोड में पूर्ववत)
  • यदि आपको DirectX के साथ .NET इंटरफ़ेस परिभाषाएँ चाहिए, तो आप इस ओपन सोर्स प्रोजेक्ट का उपयोग यहाँ कर सकते हैं: https://github.com/smourier/DirectN, उदाहरण के लिए: https://github.com/smourier/DirectN/blob/master/DirectN/DirectN/Generated/ID3D12Debug.cs