[C#] Unmanaged COM Objekte nutzen [Done]

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

[C#] Unmanaged COM Objekte nutzen [Done]

Beitrag von RazorX »

Servus,
ich will mir gerade ein kleines Tool schreiben und brauche dazu im C# die Möglichkeit den D3DCompiler anzusprechen. Der Funktionsaufruf von D3DCompile funktioniert auch und ein kleiner Testshader wird auch kompiliert (Rückgabewert ist S_OK und ich bekomme einen CodeBlob). Wenn ich dann aber versuche über GetBufferPointer() oder GetBufferSize() das Ergebnis abzufragen erhalte ich nur IntPtr.Zero bzw 0 zurück.

Code: Alles auswählen

// Definitionen
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("8BA5FB08-5195-40e2-AC58-0D989C3A0102")]
public interface ID3DBlob {
    IntPtr  GetBufferPointer();
    ulong   GetBufferSize();
};
          
[DllImport("d3dcompiler_43.dll", EntryPoint="D3DCompile", CallingConvention=CallingConvention.StdCall, PreserveSig=true)]
public static extern IntPtr Compile([In] IntPtr pSrcData, 
                                    [In] uint srcDataSize, 
                                    [MarshalAs(UnmanagedType.LPStr), In, Optional] String pSourceName, 
                                    [In, Optional]ShaderMacro[] pDefines, 
                                    [In, Optional] IntPtr pInclude,
                                    [MarshalAs(UnmanagedType.LPStr), In] String pEntryPoint, 
                                    [MarshalAs(UnmanagedType.LPStr), In] String pTarget, 
                                    [In] uint flags1, 
                                    [In] uint flags2, 
                                    [MarshalAs(UnmanagedType.Interface), Out] out ID3DBlob ppCode,
                                    [MarshalAs(UnmanagedType.Interface), Out, Optional] out ID3DBlob ppErrorMsgs);

// Aufruf
String      shader = "void vs_main(in float4 pos : POSITION, out float4 opos : SV_POSITION) { opos = pos; }";
ID3DBlob    pCode = null, pMsg = null, pDisassembly = null;
            
IntPtr  globalShader= Marshal.StringToHGlobalAnsi(shader);
IntPtr  hr          = D3D.Compiler.Compile(globalShader, (ulong)shader.Length, null, null, IntPtr.Zero, "vs_main", "vs_5_0", 0, 0, out pCode, out pMsg);
IntPtr  codePtr     = pCode.GetBufferPointer();
ulong   codeSize    = pCode.GetBufferSize();
Ich hoffe hier kennt sich jemand mit der Materie PInvoke und COM aus :) Danke im vorraus

Mit freundlichem Gruß
RazorX
Zuletzt geändert von RazorX am 06.11.2012, 17:13, insgesamt 1-mal geändert.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C#] Unmanaged COM Objekte nutzen

Beitrag von dot »

Verwend doch einfach z.B. SlimDX!?
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [C#] Unmanaged COM Objekte nutzen

Beitrag von RazorX »

Sowohl SlimDX als auch SharpDX stürzen bei mir beim Kompilieren mit einer AccessViolation ab. Ich tippe einfach mal darauf das die noch nicht so 100pro Win8 kompatibel sind. Nichtdestotrotz weigert sich bei mir innerlich auch etwas für zwei DllImport Deklaration die ich benötige eine andere Bibliothek zu nutzen. Wie gesagt der Aufruf der D3DCompile Funktion funktioniert ja, nur eben das COM-Objekt liefert nichts brauchbares.
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [C#] Unmanaged COM Objekte nutzen

Beitrag von RazorX »

Hartnäckigkeit zahlt sich aus:

Code: Alles auswählen

        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("8BA5FB08-5195-40e2-AC58-0D989C3A0102")]
        public interface ID3DBlob {
            [PreserveSig]
            IntPtr  GetBufferPointer();
            [PreserveSig]
            ulong   GetBufferSize();
        };
Mit [PreserveSig] funktionieren die Methodenaufrufe und ich habe nun Zugriff auf D3DCompile und D3DDisassemble mit einem schlanken COM-Wrapper anstelle großer Third-Party-Lib.
Antworten