Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner

can't get value correctly from fortran dll to VB.net back

Hi Everyone,
I can't make the following code working in VS2015 with IVF, though it is very simple. Value C from dll is always 0, not 6.0 as expected. Thanks so much.
//my VB code:
Public Class Form1
    Public Declare Sub DLL_ROUT Lib "D:\Debug\Dll2.dll" _
    (ByVal A As Double, ByVal B As Double, ByVal C As Double)
    Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim A As Double
        Dim B As Double
        Dim C As Double
        A = 2.0
        B = 3.0
        Call DLL_ROUT(A, B, C)
        Button1.Text = C
    End Sub
End Class
 
// my Fortran  dll code:
SUBROUTINE DLL_ROUT (A, B, C)
IMPLICIT NONE
! Specify that DLL_ROUT is exported to a DLL
! and that the external name is 'DLL_ROUT'
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: DLL_ROUT
!DEC$ ATTRIBUTES ALIAS:'DLL_ROUT' :: DLL_ROUT
DOUBLE PRECISION A, B, C
C = A * B
RETURN
END

0 Kudos
9 Replies
Highlighted
Valued Contributor III

I suggest the following based

I suggest the following instead based on P/Invoke in .NET and C interoperability in Fortran:

   <DllImport("D:\Debug\Dll2.dll", CallingConvention:=CallingConvention.Cdecl)> _
   Public Shared Sub DLL_ROUT (A As Double, B As Double, ByRef C As Double)
   subroutine DLL_ROUT(A, B, C) bind(C, name="DLL_ROUT")
   !DEC$ ATTRIBUTES DLLEXPORT::DLL_ROUT

      use, intrinsic :: iso_c_binding, only : c_double

      !.. Argument list
      real(c_double), intent(in), value :: A
      real(c_double), intent(in), value :: B
      real(c_double), intent(inout)     :: C

      C = A * B

      return

   end subroutine DLL_ROUT

 

0 Kudos
Highlighted
Black Belt

I'm not sure if FortranFan's

I'm not sure if FortranFan's suggestion will work, but the reason your initial version doesn't work is that just saying STDCALL changes the arguments to pass-by-value, which makes it impossible to return anything. Add to the Fortran:

!DEC$ ATTRIBUTES REFERENCE :: C

This will match the ByRef in the VB.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
Beginner

It works, amazing! Thanks

It works, amazing! Thanks FortranFan!

0 Kudos
Highlighted
Beginner

This is awesome, Thanks Steve

This is awesome, Thanks Steve!

0 Kudos
Highlighted
Beginner

Both works very well. Thank

Both work very well. Thank you guys!

0 Kudos
Highlighted
Valued Contributor III

Quote:Steve Lionel (Ret.)

Steve Lionel (Ret.) wrote:

I'm not sure if FortranFan's suggestion will work, ..

Huh?  It's been only >3.5 years here where readers have been guided to consider the better option with Microsoft .NET code to interoperate with Fortran is to employ P/Invoke: https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/594478

Fdll.f90

module m

   use, intrinsic :: iso_c_binding, only : c_double

   implicit none

contains

   subroutine DLL_ROUT(A, B, C) bind(C, name="DLL_ROUT")
   !DEC$ ATTRIBUTES DLLEXPORT::DLL_ROUT

      !.. Argument list
      real(c_double), intent(in), value :: A
      real(c_double), intent(in), value :: B
      real(c_double), intent(inout)     :: C

      C = A * B

      return

   end subroutine DLL_ROUT

end module m

Test.vb file

Imports System.IO
Imports System.Text
Imports System.Runtime.InteropServices

Namespace Fortran

   Public Class Fdll

      <DllImport("c:\Debug\Fdll.dll", CallingConvention:=CallingConvention.Cdecl)> _
      Public Shared Sub DLL_ROUT (A As Double, B As Double, ByRef C As Double)
      end Sub

   End Class

   NotInheritable Class Test

      Private Sub New()
      End Sub

      Public Shared Sub Main()

         Dim a As Double
         Dim b as Double
         Dim c as Double

         ' Write header
         Console.WriteLine("*** Test Fortran Interop using VB ***" + vbLf)

         Try

            a = 2.0
            b = 3.0
            c = 0.0
            Fdll.DLL_ROUT(a, b, c)

            Console.WriteLine("c = " + c.ToString("###0.0#"))

         Catch ex As Exception

            Console.WriteLine(ex.Message)

         Finally

            Console.WriteLine("Press any key to continue..")
            Console.ReadKey()

         End Try

      End Sub

   End Class

End Namespace
C:\Debug>ifort /dll /libs:static fdll.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 19.0.3.203 Build 20190206
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.16.27027.1
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:fdll.dll
-dll
-implib:fdll.lib
fdll.obj
   Creating library fdll.lib and object fdll.exp

C:\Debug>vbc -platform:x86 test.vb
Microsoft (R) Visual Basic Compiler version 2.10.0.0 (b9fb1610)
Copyright (C) Microsoft Corporation. All rights reserved.


C:\Debug>test.exe
*** Test Fortran Interop using VB ***

c = 6.0
Press any key to continue..

C:\Debug>
C:\Debug>ifort /dll /libs:static Fdll.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.3.203 Build 20190206
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.16.27027.1
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:Fdll.dll
-dll
-implib:Fdll.lib
Fdll.obj
   Creating library Fdll.lib and object Fdll.exp

C:\Debug>vbc -platform:x64 test.vb
Microsoft (R) Visual Basic Compiler version 2.10.0.0 (b9fb1610)
Copyright (C) Microsoft Corporation. All rights reserved.


C:\Debug>test.exe
*** Test Fortran Interop using VB ***

c = 6.0
Press any key to continue..

C:\Debug>

 

0 Kudos
Highlighted
Black Belt

When I said "I'm not sure" I

When I said "I'm not sure" I meant that literally - I thought it might, but am not familiar with the angle bracket syntax for use in VB code, so I didn't know. I didn't say it wouldn't work. But I knew my suggestion would work and was a smaller change.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
Valued Contributor III

Quote:Lu Zhang wrote:

Lu Zhang wrote:

It works, amazing! Thanks FortranFan!

Please see this thread from about 5 years ago, especially Quote #2 where I suggest moving away from VB6/COM based approaches with STDCALL, etc. from the bygone 1990s when it comes to working with .NET technologies:

https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/509148

0 Kudos
Highlighted
Beginner

Thank you so much, FortranFan

Thank you so much, FortranFan.

0 Kudos