Silverfrost Forums

Welcome to our forums

Fortran calls from Visual Basic

9 Aug 2011 4:12 #8760

Although there is some information concerning the interoperability (unfortunately spread over many pieces of information and for my limited knowledge too fragmented and much too complicated to be understood in detail) I could not find a solution for a very simple test problem. My idea is to call a Fortran 95 subroutine from Microsoft Visual Basic 2010 Express. This should in principle be possible via a dll. The test subroutine is

F_STDCALL Subroutine F (x,y)
integer (SELECTED_INT_KIND (9)) :: x, y
y=x
end

In Visual Basic I have created a form with a button starting the test case and an output text box. The code is

Public Class Form1

    Declare Sub F Lib 'd:\\dummy_d\\test_dll\\Release\\Win32\\Test.dll' _
       (ByRef x As Integer, ByRef y As Integer)

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim x As Integer
        Dim y As Integer
        x = 5
        F(x, y)
        TextBox1.AppendText('Call of dll: ' & y)

    End Sub
End Class

Obviously, this approach is full of errors. However, several modifications resulted in similar catastrophic errors and I am sure that I miss several essential items. I would like to add that I have created the dll with Plato. Since I suspect that there are already problems with my dll created, I would like to ask whether there is any test which proves that the dll was created correctly?

Can I find anywhere more (and complete) information or can anybody help?

Many thanks in advance for any efforts,

Klaus

9 Aug 2011 5:00 #8761

There's some information in the Knowledgebase, but really the best way to learn is to play with it like your doing. You need to know the rules of what variables in VB map to variables in Fortran.

This is my code (based on your Fortran). I compiled the Fortran without debugging using Plato. I tested the VB using Visual Studio 2008. Seems to work for me

Fortran:

F_STDCALL subroutine F(x,y)
integer*4 :: x, y
y=x
end

VB:

Declare Sub F Lib 'D:\\dll\\release\\win32\\mydll.dll' (ByRef x As Integer, ByRef y As Integer)

Sub try()

  Dim x As Integer, y As Integer
  x = 5
  Call F(x, y)
  ' y now contains 5 (checked in VB debugger)

End Sub
10 Aug 2011 10:56 #8770

David, thank you very much for your help. How exactly have you created the library mydll.dll? I am quite sure that I am continuously making an error in creating the dll. (It is my first dll!) One indication for a fault is that the size of my dll is always 10752, independently of the code. I use Plato (File...New Project... Fortran-DLL...Name:mydll...Location = selected directory. When I build the project I receive the messages Compilung file:f.f95 Compiling completed with no errors Linking.... WARNING-Default LibMain being provided.

I am sorry, for asking help for obviously simple problems.

Klaus

10 Aug 2011 12:49 #8771

PS. I have tried also to create a dll in Silverfrost FTN95 Express as well as in Visual studio. I have set Win32 whereever possible. However, in both systems the creation fails with something like

/////////////////////////////////////

Build log for project: Test_dll
Configuration: Release/Win32
Date: 10/8/2011 - 14:41:50

/////////////////////////////////////

System Configuration
////////////////////

Path Directories:
C:\\Program Files\\Silverfrost\\FTN95
C:\\WINDOWS\\system32
C:\\WINDOWS
C:\\WINDOWS\\System32\\Wbem
d:\\bin
C:\\Program Files\\Common Files\\Acronis\\SnapAPI\C:\\Program Files\\Common Files\\Apple\\Mobile Device Support
C:\\Program Files\\Common Files\\Apple\\Apple Application Support
C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0
C:\\Program Files\\QuickTime\\QTSystem\C:\\Program Files\\Microsoft SQL Server\\100\\Tools\\Binn\C:\\Program Files\\Microsoft SQL Server\\100\\DTS\\BinnProject Directory: D:\\IDEs\\FTN95 Express\\Test_dll\\Test_dll\Output Directory: D:\\IDEs\\FTN95 Express\\Test_dll\\Test_dll\\Release\\Win32
Output File: Release\\Win32\\Test_dll.dll

Project Build
/////////////

   D:\\IDEs\\FTN95 Express\\Test_dll\\F.f95

Compiling...

Compiling file: F.f95
FTN95.EXE 'D:\\IDEs\\FTN95 Express\\Test_dll\\F.f95' /NO_BANNER /P6 /FPP/REF 'C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727\\System.dll' /REF 'C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727\\System.Data.dll' /REF 'C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727\\System.XML.dll' /VS8 /DELETE_OBJ_ON_ERROR /ERROR_NUMBERS /UNLIMITED_ERRORS /BINARY 'Release\\Win32\\F.obj'

Linking...

Command line for link:
   slink.exe -DLL -OUT:'Release\\Win32\\Test_dll.dll' @'D:\\IDEs\\FTN95 Express\\Test_dll\\Test_dll\\link.lst' 'C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727\\System.dll' 'C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727\\System.Data.dll' 'C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727\\System.XML.dll'
Linker output: 
   *** Cannot create DLL: nothing to export


Test_dll build failed.

/////////////////////////////////////

I simply do not see anything else which I could set.

10 Aug 2011 1:46 #8774

Quoted from KL David, thank you very much for your help. How exactly have you created the library mydll.dll? I am quite sure that I am continuously making an error in creating the dll. (It is my first dll!) One indication for a fault is that the size of my dll is always 10752, independently of the code. I use Plato (File...New Project... Fortran-DLL...Name:mydll...Location = selected directory. When I build the project I receive the messages Compilung file:f.f95 Compiling completed with no errors Linking.... WARNING-Default LibMain being provided.

I am sorry, for asking help for obviously simple problems.

Klaus

No problem. Ask away and I will try to help.

If your DLL is not changing size, are you sure you are looking at the right file? Are you building a Debug or Checkmate one in another directory and testing your VB code on a non--working one in the Release Directory? Alternatively, did you put a copy of test_dll.dll in your system folder?

For reference mydll.dll is size 10752 bytes (should be the same as yours)

If you have several output sub-directories (Release, Debug, Checkmate) its best to delete these and build again.

These are the steps I used:

  • I am using version 6.1.00 of the compiler.
  • I have used Plato. File → New Project → Fortran DLL.
  • Goto project properties, linker options. Make sure export all is ticked and no others.
  • Then I change from Checkmate Win32 to Release Win32
  • I type in your Fortran code and Build.
  • I get the Warning about the default LibMain too, that is ok.
  • After the build, the DLL is in the Release\Win32 sub-directory.
  • The DLL is finished now and I write the VB code.

Building DLLs with the FTN95 Express might be a little different. I can have a look at this but please check the above and stay with Plato for a little longer.

David.

10 Aug 2011 2:44 #8775

David, I had done everything exactly as you described it. There is no mixing between different modes. In order to be 100% sure I deleted everything and started from scratch again. The dll was produced and should be OK.

What exactly do you mean by

'Alternatively, did you put a copy of test_dll.dll in your system folder?'

I guess that you worked with a console application. I inserted exactly your program and adapted the path of the library. I got the following warning:

An unhandled exception of type 'System.StackOverflowException' occurred in ConsoleApplication1.exe .

Klaus

10 Aug 2011 3:46 #8777

I was just making sure you don't have a test_dll.dll file in C:\Windows\System32.

Let's assume your DLL is OK and the problem is with your VB. I used VB Express 2008 (you have VB 2010).

Try using your DLL with my VB client, and with a Fortran Client. This should tell you where the problem lies.

Here is my VB console application. I just typed it in and everying worked first time. Its pretty simple. You just need to change the declaration to put in the path to your DLL. (Works for me when I look at y in the debugger it is 5.)

Module Module1

    Declare Sub F Lib 'D:\\dll\\release\\win32\\mydll.dll' (ByRef x As Integer, ByRef y As Integer)

    Sub Main()
        Dim x As Integer, y As Integer
        x = 5
        F(x, y)
        ' y now contains 5 (checked in VB debugger)
    End Sub

End Module

Here is the Fortran application. Make a new project in Plato. Add this source, and also add your DLL as a reference. (I just right click in the project window and select add existing files.) Run the code it should print 5. (It does for me!)

program client

F_STDCALL F (VAL, VAL)

integer*4 :: x, y

x = 5
call F(x, y)
print *, y

end program client

If one of these works, your DLL is ok. If the Fortran works and the VB doesn't the problem is with your VB.

10 Aug 2011 4:38 #8778

Many thanks, David.

The Fortran project runs correctly, however, Visual Studio 2010 and Visual Basic 2010 Express fail with 'Stack Overflow'. Of course I have exactly used your code except for adapting the path to the dll file.

I have run numerous examples with Visual Studio and Visual Basic Express successfully and I am pretty convinced that both have been installed correctly (I cannot influence anyhow the installation). Both are the latest versions.

Tomorrow I will repeat all steps again.

Many thanks again for your help,

Klaus

10 Aug 2011 5:00 #8779

PS. Start debugging fails in Visual Basic Express, but Start without debugging works correctly.

Please login to reply.