12:06
Great article
The tools I've chosen to utilize for this little project will be G95, the open source Fortran comiler, and Visual Studio 2010 to create the Visual Basic project. The express edition of Visual Studio is completely free, so using these tools should not limit anyone in following along in all the steps I outline. When I started out on this project for myself, I had absolutely zero knowledge of Fortran, so I'm going to assume the reader has limited knowledge as well. It's a tricky process learning a language and creating DLL files at the same time.
So to begin, make sure you download the G95 installer from the G95 project website. After installing, make sure it installed correctly by typing in "g95" without the quotes at the command prompt. It should send back the string "g95: no input files". If it responds telling you g95 is not recognized, you have not yet installed g95, or the installer did not run correctly.
So, onto our first file in Fortran. Open up some kind of text editor that does not allow rich text formatting. Notepad is the most basic, but I myself prefer Notepad++. Interestingly enough, when writing Fortran files to be exported as a DLL, there are absolutely zero special constructions or keywords that we need to learn to be able to do so. We will only write the functions and subroutines to be exported. There will be no main body, or anything of that nature in the file. So, let's begin with a very basic example of a function in Fortran, and I'll explain a little bit of what's happening in each part.
function ex1(i)
integer*4 :: ex1, i
ex1=i+1
return
end function
So, let's examine this small method part by part. The function keyword should be familiar, it tells the compiler that this method will have some kind of value returned from it. If we preferred instead that the method returned no value, we would instead use the word "subroutine". ex1 will be the name of the method, and also the name of the variable that this function will be returning. This may be a bit of a change for you if you are unfamiliar with Fortran. This is why at the end of the function, we see simply a "return" statement without a variable specified to return. The function will simply return the value of the variable with the same name as the function. In this case, we specified the value of ex1 the line beforehand, so it should be clear what it is the function is returning.EXPORTS sweetFunction = ex1_
Note the use of the underscore. The left side of the equals sign tells us the name external programs will see as the name of this method. The right side tells us what method we are referencing. If we wanted instead to maintain the same name for our external program, we would instead use:
EXPORTS ex1 = ex1_
And that is all we will be putting in our small file. Save it is test.def.
I do have one question here. I followed your instruction to create the Fortran DLL, but when I try to access it via MS VB Express 2010, I get this error:
"A first chance exception of type 'System.AccessViolationException' occurred in FortranTesting.exe".
My function is called "ex1", the DLL is called "ftest.dll" and my VB code is as shown:
Imports System
Imports System.Runtime.InteropServices
Public Class Form1
_
Public Shared Function ex1(ByVal number As Integer) As Integer
End Function
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim testnum As Integer
testnum = 5
Dim test As Integer = ex1(testnum)
MsgBox("Finished!")
End Sub
End Class
....Any ideas where I'm going wrong?
I do have one question here. I followed your instruction to create the Fortran DLL, but when I try to access it via MS VB Express 2010, I get this error:
"A first chance exception of type 'System.AccessViolationException' occurred in FortranTesting.exe".
My function is called "ex1", the DLL is called "ftest.dll" and my VB code is as shown:
Imports System
Imports System.Runtime.InteropServices
Public Class Form1
_
Public Shared Function ex1(ByVal number As Integer) As Integer
End Function
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim testnum As Integer
testnum = 5
Dim test As Integer = ex1(testnum)
MsgBox("Finished!")
End Sub
End Class
....Any ideas where I'm going wrong?
...Sorry for the multiple posts...got trigger happy with the mouse button apparently :)...Also, my code didn't post properly. The correct version is here:
Imports System
Imports System.Runtime.InteropServices
Public Class Form1
_
Public Shared Function ex1(ByVal number As Integer) As Integer
End Function
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim testnum As Integer
testnum = 5
Dim test As Integer = ex1(testnum)
MsgBox("Finished!")
End Sub
End Class
...any help is much appreciated!
It was really helpful.
For an VBA/Excel Fortran DLL, I used the following command to create the DLL file :
g95 -s -shared -mrtd -o test.dll test.def test.o
I am getting the ' Attempted to read or write protected memory. This is often an indication that other memory is corrupt. ' error in my c# application while calling the ex1(p).
Can you please tell me how to call this function