title: VB.NET calling Fortran: how to fix PInvoke exception?
body: <p>In working up a simple example of VB calling fortran, I'm getting two errors depending on what approach I try to take.  While the following small reproducible example below is simple, it is a precursor to a much larger problem.  </p>
  
  <p>The primary goal of this simple example is to adjust the value of an argument passed to the Fortran code (in this case, "SUMMATION") and then use the returned (and adjusted) value in VB.</p>
  
  <p>I first offer the simple fortran code, then show the two variations of VB code used to call it along with the error message each approach results in.</p>
  
  <p><strong>The Fortran code called by VB:</strong></p>
  
  <pre><code>SUBROUTINE MFNWT_RUN(KSTP,KPER,SUMMATION) 
  
      !DEC$ ATTRIBUTES DLLEXPORT :: MFNWT_RUN
      !DEC$ ATTRIBUTES ALIAS: "MFNWT_RUN" :: MFNWT_RUN
  
      IMPLICIT NONE
  
      INTEGER, Intent(in) :: KPER, KSTP
      INTEGER, Intent(inout) :: SUMMATION
  
      INTEGER kkper, kkstp
      INTEGER add_em_up
  
      kkper = KPER
      kkstp = KSTP
  
      add_em_up = kkper + kkstp
  
      SUMMATION = add_em_up 
  
  END SUBROUTINE
  </code></pre>
  
  <p><strong>The calling VB code (first approach):</strong></p>
  
  <pre><code>Imports System.Collections
  Imports System
  Imports System.Runtime.InteropServices
  Imports System.IO
  Imports System.Data
  
  Module Module1
  
      &lt;DllImport("example_fortran_directory.dll", CallingConvention:=CallingConvention.StdCall)&gt;
      Public Function MFNWT_RUN(ByVal a As Integer, ByVal b As Integer, ByRef Divs As Integer)  'ref bool AdvFlwRdr
      End Function
  
      ' Private Declare Sub MFNWT_RUN Lib "example_fortran_directory.dll" Alias "MFNWT_RUN" (&lt;[In](), Out()&gt; ByRef A As Integer, ByRef B As Integer, ByRef C As Integer)
      'Declare Sub MFNWT_RUN Lib "example_fortran_directory" (ByRef A As Integer, ByRef B As Integer, ByRef C As Integer)
  
      Sub Main()
          Dim first As Integer
          Dim second As Integer
  
          Dim answer As Integer
  
          first = 6
          second = 7
          answer = 0
          Call MFNWT_RUN(first, second, answer)
  
          MsgBox(answer)
  
      End Sub
  
  End Module
  </code></pre>
  
  <p>Gives the error:</p>
  
  <p><a href="https://i.stack.imgur.com/SJ5H3.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/SJ5H3.png" alt="enter image description here"></a></p>
  
  <p>If instead I try and 'wire-up' the call to the Fortran DLL a bit differently (comment out the DllImport code and uncomment the declare code), I get a different error.  </p>
  
  <p><strong>The calling VB code (second approach):</strong></p>
  
  <pre><code>Imports System.Collections
  Imports System
  Imports System.Runtime.InteropServices
  Imports System.IO
  Imports System.Data
  
  Module Module1
  
      ' Private Declare Sub MFNWT_RUN Lib "example_fortran_directory.dll" Alias "MFNWT_RUN" (&lt;[In](), Out()&gt; ByRef A As Integer, ByRef B As Integer, ByRef C As Integer)
      Declare Sub MFNWT_RUN Lib "example_fortran_directory" (ByRef A As Integer, ByRef B As Integer, ByRef C As Integer)
  
      Sub Main()
          Dim first As Integer
          Dim second As Integer
  
          Dim answer As Integer
  
          first = 6
          second = 7
          answer = 0
          Call MFNWT_RUN(first, second, answer)
  
          MsgBox(answer)
  
      End Sub
  
  End Module
  </code></pre>
  
  <p>Gives the following exception:</p>
  
  <p><a href="https://i.stack.imgur.com/fA8pY.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/fA8pY.png" alt="enter image description here"></a></p>
  
  <p>This second approach works - meaning if I acknowledge the error I can move past it, but I would prefer to fix the underlying issue if someone can direct me how to do so? The larger problem I'm aiming to address will be making thousands of calls to Fortran from VB, so it would seem vital that I fix the stack imbalance error the right way (and not just turn off the warning message).  </p>
  
  <hr>
  
  <p>Appending another attempt that also resulted in the PInvokeStackImbalance error.  </p>
  
  <p><strong>First the fortran:</strong></p>
  
  <pre><code>   SUBROUTINE MFNWT_RUN(KSTP,KPER,SUMMATION)
  
      !DEC$ ATTRIBUTES DLLEXPORT, ALIAS: 'MFNWT_RUN' :: MFNWT_RUN
      !DEC$ ATTRIBUTES REFERENCE :: KSTP
      !DEC$ ATTRIBUTES REFERENCE :: KPER
      !DEC$ ATTRIBUTES REFERENCE :: SUMMATION
  
      IMPLICIT NONE
  
      INTEGER, value :: KPER, KSTP
      INTEGER, value :: SUMMATION
  
      INTEGER kkper, kkstp
      INTEGER add_em_up
  
      kkper = KPER
      kkstp = KSTP
  
      add_em_up = kkper + kkstp
  
      SUMMATION = add_em_up 
  
  END SUBROUTINE MFNWT_RUN
  </code></pre>
  
  <p><strong>And the calling VB:</strong></p>
  
  <pre><code>Imports System.Collections
  Imports System
  Imports System.Runtime.InteropServices
  Imports System.IO
  Imports System.Data
  
  Module Module1
  
  Private Declare Sub MFNWT_RUN Lib "example_fortran_directory.dll" Alias "MFNWT_RUN" (&lt;[In](), Out()&gt; ByRef A As Integer, ByRef B As Integer, ByRef C As Integer)
  
  Sub Main()
      Dim first As Integer
      Dim second As Integer
  
      Dim answer As Integer
  
      first = 6
      second = 7
      answer = 0
      Call MFNWT_RUN(first, second, answer)
  
      MsgBox(answer)
  
  End Sub
  
  End Module
  </code></pre>
  
  <p>This approach also ended in the PInvokeStackImbalance exception being thrown.  First, I'm wondering if this exception is a big deal (i.e., should I simply uncheck it - meaning the code should move on and not warm me when this exception is thrown)?  If it is something that should be fixed (I would assume this to be the case), and you see what my problem is, please help.  </p>