Реализация D3DCompileFromFile в VB.NET дает мне несбалансированный стек. ошибка

Я взял части кода из редактора шейдеров Shazzam (http://shazzam.codeplex.com/) и изменил код для использования файла Compile From вместо памяти (https://msdn.microsoft.com/en-us/library/windows/desktop/hh446872(v=vs.85).aspx)

 <Guid("8BA5FB08-5195-40e2-AC58-0D989C3A0102"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
    Private Interface ID3DBlob
        <PreserveSig> _
        Function GetBufferPointer() As IntPtr
        <PreserveSig> _
        Function GetBufferSize() As Integer
    End Interface

    <PreserveSig> _
    <DllImport("d3dcompiler_47.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.Cdecl)> _
    Private Function D3DCompileFromFile(<MarshalAs(UnmanagedType.LPTStr)> pFilename As String,
                                                          pDefines As IntPtr,
                                                          pInclude As IntPtr,
                                                          <MarshalAs(UnmanagedType.LPTStr)> pEntrypoint As String,
                                                          <MarshalAs(UnmanagedType.LPTStr)> pTarget As String,
                                                          flags1 As Integer,
                                                          flags2 As Integer,
                                                          ByRef ppCode As ID3DBlob,
                                                          ByRef ppErrorMsgs As ID3DBlob) As Integer
    End Function

    Public Sub Compile(ByVal File As HLSLFileHelperClass)
        Dim pFilename As String = File.GetSourceFileFullName ' C:\MyPSFiles\GaussianFilter.fx
        Dim pDefines As IntPtr = IntPtr.Zero
        Dim pInclude As IntPtr = IntPtr.Zero

        Dim pEntrypoint As String = File.HLSLEntryPoint ' main
        Dim pTarget As String = File.ShaderCompilerVersion.ToString ' ps_3_0

        Dim flags1 As Integer = 0
        Dim flags2 As Integer = 0
        Dim ppCode As ID3DBlob
        Dim ppErrorMsgs As ID3DBlob

        Dim CompileResult As Integer = 0

        CompileResult = D3DCompileFromFile(pFilename,
                                           pDefines,
                                           pInclude,
                                           pEntrypoint,
                                           pTarget,
                                           flags1,
                                           flags2,
                                           ppCode,
                                           ppErrorMsgs)

        If CompileResult <> 0 Then

            Dim errors As IntPtr = ppErrorMsgs.GetBufferPointer()

            Dim size As Integer = ppErrorMsgs.GetBufferSize()

            ErrorText = Marshal.PtrToStringAnsi(errors)
            IsCompiled = False
        Else
            ErrorText = ""
            IsCompiled = True
            Dim psPath = File.GetCompiledFileFullName
            Dim pCompiledPs As IntPtr = ppCode.GetBufferPointer()
            Dim compiledPsSize As Integer = ppCode.GetBufferSize()

            Dim compiledPs = New Byte(compiledPsSize - 1) {}
            Marshal.Copy(pCompiledPs, compiledPs, 0, compiledPs.Length)
            Using psFile = IO.File.Open(psPath, FileMode.Create, FileAccess.Write)
                psFile.Write(compiledPs, 0, compiledPs.Length)
            End Using
        End If

        If ppCode IsNot Nothing Then
            Marshal.ReleaseComObject(ppCode)
        End If
        ppCode = Nothing

        If ppErrorMsgs IsNot Nothing Then
            Marshal.ReleaseComObject(ppErrorMsgs)
        End If
        ppErrorMsgs = Nothing


    End Sub

Код в том виде, в каком он есть сейчас, дает мне ошибку:

Вызов функции PInvoke '::D3DCompileFromFile' привел к разбалансировке стека. Вероятно, это связано с тем, что управляемая подпись PInvoke не соответствует неуправляемой целевой подписи. Убедитесь, что соглашение о вызовах и параметры подписи PInvoke соответствуют целевой неуправляемой подписи.

Если я удалю строку:

CallingConvention:=CallingConvention.Cdecl

Кажется, компилятор запускается, но теперь я получаю сообщение об ошибке:

X3506 нераспознанная цель компилятора 'p'

Кажется, вы только что прочитали первый символ в строке? Итак, что я делаю неправильно здесь?


person Kenneth Haugland    schedule 27.05.2015    source источник


Ответы (1)


Получил это работает, и я сделал две вещи:

Сначала я переместил все это в модуль:

Module Extend
    <Guid("8BA5FB08-5195-40e2-AC58-0D989C3A0102"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
    Public Interface ID3DBlob
        <PreserveSig> _
        Function GetBufferPointer() As IntPtr
        <PreserveSig> _
        Function GetBufferSize() As Integer
    End Interface

    <PreserveSig> _
    <DllImport("d3dcompiler_47.dll", CharSet:=CharSet.Auto)> _
    Public Function D3DCompileFromFile(<MarshalAs(UnmanagedType.LPTStr)> pFilename As String,
                                                          pDefines As IntPtr,
                                                          pInclude As IntPtr,
                                                          <MarshalAs(UnmanagedType.LPStr)> pEntrypoint As String,
                                                          <MarshalAs(UnmanagedType.LPStr)> pTarget As String,
                                                          flags1 As Integer,
                                                          flags2 As Integer,
                                                          ByRef ppCode As ID3DBlob,
                                                          ByRef ppErrorMsgs As ID3DBlob) As Integer
    End Function
End Module

Во-вторых, я изменил:

<MarshalAs(UnmanagedType.LPTStr)>

to

<MarshalAs(UnmanagedType.LPStr)>

Кажется, я немного расстроился и изменил то, что тоже сработало :S

person Kenneth Haugland    schedule 27.05.2015