×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

How to make DLL's in fortran
2

How to make DLL's in fortran

How to make DLL's in fortran

(OP)
Hi,

I want to compile some fotran code to a DLL to be used by a commercial code and to be tested by my own fortran executable.

How do I do this?

Where can I find how to do this in gfortran and in CVF (but I'm especially interested in the gfortran option)?

Once compiled to a DLL, how do I call my DLL from my fortran code? (This is only to test it, in reality it will be used and called by some commercial code)

Any info or link to a manual is welcome, I couldn't find any hit on the search "DLL" in the user unfriendly manual at: gcc.gnu.org/onlinedocs/gcc-4.2.1/gfortran.pdf

Thanks,

Gerrit

RE: How to make DLL's in fortran

In CVF, to create File/New/Project, pick Intel Fortran and there is a DLL option as on of the projects.

Usage, see http://www.tek-tips.com/viewthread.cfm?qid=1571100&page=1

Don't know about gfortran - instructions for Linux may be different from instructions for windows.

 

RE: How to make DLL's in fortran

With gfortran it works like with g95, which is described here: http://www.g95.org/g95_dll.shtml

I tried it:

1. I created a source for the dll named dll_foo.f95

CODE

integer function add2i(x, y)
  integer, intent(in) :: x, y
  add2i = x + y
end function add2i

real function add2r(x, y)
  real, intent(in) :: x, y
  add2r = x + y
end function add2r

real function simpson(f, a, b, n)
  ! Approximate the definite integral of f from a to b by the
  ! composite Simpson's rule, using N subintervals
  ! see: <a href="http://en.wikipedia.org/wiki/Simpson%27s_rule">http://en.wikipedia.org/wiki/Simpson%27s_rule</a>
  ! function arguments ---------------------
  ! f: real function
  interface
    real function f(x)
      real, intent(in) :: x
    end function f
  end interface
  ! [a, b] : the interval of integration
  real, intent(in) ::  a, b
  ! n : number of subintervals used
  integer, intent(in) :: n
  ! ----------------------------------------
  ! temporary variables
  integer :: k
  real :: s
  s = 0
  do k=1, n-1
    s = s + 2**(mod(k,2)+1) * f(a + (b-a)*k/n)
  end do  
  simpson = (b-a) * (f(a) + f(b) + s) / (3*n)
end function simpson
2. Then I compiled the dll source with

CODE

$ gfortran -c dll_foo.f95
$ gfortran -shared -mrtd -o dll_foo.dll dll_foo.o
The file dll_foo.dll was created.
Btw, when you want to look into the dll what functions it exports, then there is a free utility for it: Dependency Walker

3. Then I created the Fortran program, which should use the dll created in previous steps:
dll_foo_test.f95

CODE

program simpson_test
  implicit none
  integer :: add_i
  real :: integral, add_r
  integer, external :: add2i
  real, external :: f1, add2r, simpson
  
  add_i = add2i(1, 2)
  write (*,*) "add 2 integers = ", add_i  
  add_r = add2r(2.71, 3.14)
  write (*,*) "add 2 reals    = ", add_r  
  integral=simpson(f1, 0.0, 1.0, 1000)
  write (*,*) "Simpson's rule = ", integral  
end program simpson_test

real function f1(x)
  implicit none
  real, intent(in) :: x
  f1 = x*x
end function f1
and I compiled it into executable with

CODE

$ gfortran -o dll_foo_test dll_foo_test.f95 -L. dll_foo.dll
Now when I run it, the output is:

CODE

$ dll_foo_test                                 
 add 2 integers =            3
 add 2 reals    =    5.8500004    
 Simpson's rule =   0.33333328    
It works.

RE: How to make DLL's in fortran

Took a while to get PowerStation going.  Forgot that it had to be installed in a directory with no spaces in the filename!  The C1007 and F1019 really had me foxed for ages.

Anyway, Powerstation generates names with an argument count.  You need to add an _ in front of the name, and an @ and the number of parameters * 4.  Say you have a subroutine to add 2 numbers and return a result.

CODE

subroutine ADD (a, b, c)
real a, b, c
a = b + c
return
end
You need to create a .def file (say test.def).  Note that all keywords must be in uppercase

CODE

LIBRARY testlib
EXPORTS
   _ADD@12
Click on settings.  Under project options, add

CODE

/def:test.def
Build and you should get the DLL (ends with .dll) and its stub (ends with .lib).  When you link with an exe, use the stub.  Put the DLL in the same directory as the executable and you should be able to run it.

Another way of exporting if you do not wish to use a .def file is to add the name of the routine in the Project options

CODE

/export:_ADD@12
Note that this is /export but in the .def file it is EXPORTS

RE: How to make DLL's in fortran

(OP)
Hi,

Back again, sorry for reacting that late, I was on a trip, I used @mikrom and @xwb to answer.

@mikrom:

Thanks! Works great!

As well as the dll as the executable build and compile perfectly.

I tried to separate compiling and building (a matter of taste to see what I'm doing) and used a batch file like:

CODE

REM DLL compile
gfortran -c sub_twice.f90
REM DLL build
gfortran -shared -mrtd -o sub_twice.dll sub_twice.o
REM EXE compile
gfortran -c main.f90
REM EXE build
gfortran main.o -o main.exe -L. sub_twice.dll

With the simple code for the dll

CODE

SUBROUTINE Twice(x,y)
IMPLICIT NONE
REAL, INTENT(IN) :: x
REAL, INTENT(OUT) :: y
y=2*x
END SUBROUTINE Twice

And for the executable

CODE

SUBROUTINE Twice(x,y)
IMPLICIT NONE
REAL, INTENT(IN) :: x
REAL, INTENT(OUT) :: y
y=2*x
END SUBROUTINE Twice

What amazes me a bit is that we don't need to use something in the dll like:

CODE

!DEC$ ATTRIBUTES DLLEXPORT::Twice
And in the exe something like:

CODE

!DEC$ ATTRIBUTES DLLIMPORT::Twice

...or !GCC$

It seems to work fine without these compiler commands that seem to be called "compiler directives"... ???
I suppose that the necessity to use these commands is compiler dependent

Thanks for the tip about Dependency Walker, I'll use it to check commercial dll's. Checking my own dll gives:
"twice_" as the function name indeed on the export window. You can't see which variables are going in or out, can you?
When I load the executable, it doesn't show "twice_" on the PI import window however, I suppose that Dependency Walker only works with DLL's, right?

Something that doesn't have to do anything with building DLL's but that I saw in your example and was new to me, is that you seem to use your function f1 as an argument to your function simpson ??
Is it therefore necessary to use the "INTERFACE" statement in the function "simpson"?? (Never knew what these interfaces were for anyway...) Amazing, I didnt know it existed!

@xwb:

Thanks for looking up your fortran power station compiler!!

The first thing I noticed is that you either used "compiler directives" like !DEC$ etc., are these not necessary?

About the def file, it's not clear to me whether the name of the library, in your case "testlib" should be the same as the name of your DLL, or the function in your DLL.

Using only 2 variables, I get indeed a message that _TWICE@8 is missing, which meets perfectly the name convention you mentioned.

So, I made a file "twice.def" that contains:

CODE

LIBRARY sub_twice
EXPORTS
   _TWICE@8

Adding that to my project options in the DLL workspace it looks like

CODE

/Ox /I "Release/" /c /nologo /MT /Fo"Release/  /def:twice.def "

But the lib file is not generated....???

Adding "/export:_TWICE@8" does not work either, I tried in the DLL workspace and in the EXE workspace before building, again I get the message that _TWICE@8 is missing...

After all, it seems very complicated and laborious in Developer Studio

P.S.: About the old power station, you mention the spaces in the directory name. Be careful using directory names longer than 8 characters with this compiler, the debug function only works for directory names upto 8 characters!!

Regards,

Gerrit
 

RE: How to make DLL's in fortran

The !DEC stuff only works for the CVF/IVF compiler.  On the CVF/IVF compilers, there are currently 3 ways of doing this - that happens to be the oldest and is supported by all the older compilers.

RE: How to make DLL's in fortran

Quote (GerritGroot):


It seems to work fine without these compiler commands that seem to be called "compiler directives"... ???I suppose that the necessity to use these commands is compiler dependent
I don't know, but I think too, that these directives are only for the another compiler. As I don't use fortran at professional level I don't have experience with commercial compilers.

Quote (GerritGroot):


Thanks for the tip about Dependency Walker, I'll use it to check commercial dll
...
You can't see which variables are going in or out, can you?
...
I suppose that Dependency Walker only works with DLL's, right?
I discovered Dependency Walker as I tried to call my own dll using Python - but without success sad
I thing the same as you about variables and that it works only with dll's, but maybe I don' have expereince.
(Maybe it's off topic, but if you know how to call a dll generated from g95 or gfortran in Perl, Python, Ruby, ... you could post it here.)

Quote (GerritGroot):


Is it therefore necessary to use the "INTERFACE" statement in the function "simpson"?? (Never knew what these interfaces were for anyway...) Amazing, I didnt know it existed!
No!
I coded the Simpson's method here without interface
dll_foo2.f95

CODE

integer function add2i(x, y)
  integer, intent(in) :: x, y
  add2i = x + y
end function add2i

real function add2r(x, y)
  real, intent(in) :: x, y
  add2r = x + y
end function add2r

real function simpson(f, a, b, n)
  ! Approximate the definite integral of f from a to b by the
  ! composite Simpson's rule, using N subintervals
  ! see: <a href="http://en.wikipedia.org/wiki/Simpson%27s_rule">http://en.wikipedia.org/wiki/Simpson%27s_rule</a>
  ! function arguments ---------------------
  ! f: real function  
  real :: f
  ! [a, b] : the interval of integration
  real, intent(in) ::  a, b
  ! n : number of subintervals used
  integer, intent(in) :: n
  ! ----------------------------------------
  ! temporary variables
  integer :: k
  real :: s
  s = 0
  do k=1, n-1
    s = s + 2**(mod(k,2)+1) * f(a + (b-a)*k/n)
  end do  
  simpson = (b-a) * (f(a) + f(b) + s) / (3*n)
end function simpson
It compiles and runs:

CODE

$ gfortran -c dll_foo2.f95
$ gfortran -shared -mrtd -o dll_foo2.dll dll_foo2.o
$ gfortran -o dll_foo_test dll_foo_test.f95 -L. dll_foo2.dll
$ dll_foo_test                                  
 add 2 integers =            3
 add 2 reals    =    5.8500004    
 Simpson's rule =   0.33333328    
The above code works. But when the argument function should return something complicated as a number, e.g. vector then the declaration would be not so simple. So as a prophylactic, since the discussion given here http://www.tek-tips.com/viewthread.cfm?qid=1572869&amp;page=1 I'm rather using interfaces. Maybe it's little bit verbose but I like it!
smile

RE: How to make DLL's in fortran

(OP)

Quote:


(Maybe it's off topic, but if you know how to call a dll generated from g95 or gfortran in Perl, Python, Ruby, ... you could post it here.)

No, unfortunately I don't know that, I only know fortran and what I know about DLL's is what I read on this forum.

I have sort of the inverse problem, I'll have to find out how to make a DLL in fortran that fulfills certain commercial code call conventions (no idea how to do that?).

Thanks all for your answers!

 

RE: How to make DLL's in fortran

Are you sure about this one

CODE

/Ox /I "Release/" /c /nologo /MT /Fo"Release/  /def:twice.def "
These are the flag for Fortran - the /def should not be added here.  It should be added for the linker.  Your Fortran flags should read

CODE

/Ox /I "Release/" /c /nologo /MT /F"Release/"
The linker flags should read something like

CODE

/nologo /subsystem:console /dll /def:"twice.def" /out:"release/twice.dll" /implib:"release/twice.lib"
The name after LIBRARY has to match that of the dll otherwise the linker will moan about it.

RE: How to make DLL's in fortran

(OP)
Once again, sorry for reacting so late.

It seems to work, thanks!

Nevertheless, it's very complicated in Microsoft's compiler, much more complicated than in gfortran.

Gerrit

RE: How to make DLL's in fortran

The newer MS compilers have streamlined the process but you still need a few extras (ImportDLL etc) - basically the MS route isn't as streamlined as the *nix route.  I found that when I first started using Windows in 1986.  Powerstation has been around since 2000 - it was the replacement for MSFortran (I still have a copy of that somewhere!) but MS still needs some directive to tell it which routines to export.

The def table can be extended to hardcode the offset of the routine.  It is basically a jump table so all exported routines will have a location.  This means that if you send a DLL to a customer, you can be sure that there won't be any linkage problems because the routine has moved location in the jump table.

With the Import DLL technique, you can't just do a DLL swap.  You need to export the whole suite, which can be costly.  That is the only problem I had with *nix: if any new routines were added, you almost always had to export the whole suite.
 

RE: How to make DLL's in fortran

(OP)
Thanks! Being only a technical user, it's it bit hard for me to understand you, because of my lack of knowledge on the subject.

Anyway, I assume you mean that you can't just interchange DLL's for the same exe if they're compiled with gfortran, right?

Nevermind, my problems are solved and the stuff compiles.

(The only reason I use Microsoft's compiler, is because of their easy debugging mode and their colorful editor. As far as I know, debugging in gfortran can only be done in a very old-fashioned way, placing "WRITE(*,*)" everywhere...    ...I, did that on those green screens in the 80's...)

RE: How to make DLL's in fortran

Quote (GerritGroot):


The only reason I use Microsoft's compiler, is because of their easy debugging mode and their colorful editor. As far as I know, debugging in gfortran can only be done in a very old-fashioned way, placing "WRITE(*,*)" everywhere...
Produces Micorsoft recently a Fortran compiler?
I searched a web, but found nothing. In the 90's I had a MS Fortran 5. This compiler was running on Windows, but in DOS-like IDE called Workbench.

It would not be generally so tragic with developing in gfortran or g95 on Windows as you think. There are some free tools available.
You can use for editing any of the free available editors, which supports syntax highlighting - im using vim.
For debugging I'm using gdb with GUI called insight. The complete binary insight-6.6-mingw.tar.bz2, which I have installed, is available here. But maybe there is newer version.
It's probably not so comfortable as your IDE, but I'm doing nothing big in Fortran.
For bigger projects I would try Photran.
  

RE: How to make DLL's in fortran

Use the dependency walker and compare the offsets of the routines in both the original DLL and the new DLL.  If they are the same then they are compatible and you can just do a DLL swap.  If they are different, you might have to do the whole suite.

Sometimes you may think this is a painfully tedious task.  The GNU suite has tedium saving tools for such things.

Also a lot depends on the company policies.  Is it always full installs with no patches or do they allow patches.  If it is always full installs, then don't worry about it.  If they allow patches then you really need to keep the patches as small as possible otherwise you end up with some patch like VS2005 SP1 which in turn needs a patch on Windows 2003 before it can install.
 

RE: How to make DLL's in fortran

(OP)
Hi,

It took me long this time, I had a virus!! Well, not me, but my computer got the mexican flew.

Just wanted to say thanks to the last two posts.

@mikrom
 Thanks for the editor info, I have been looking for that for quite some time.

@xwb
 The DLL is supposed to be interchangeable, the commercial software provider wants the user to interchange them and describes what the dll should fullfill (in one page, without telling you how to make it...)

Regards,

Gerrit

P.S.: A patch that needs a patch... ...sounds like windows indeed. We need a windows compatible free OS (because the man on the street is unable to work with linux)

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close