Linking FORTRAN libraries

I am using Root 5.34.17 under windows. I want to compile a C++ script under root and link to it external FORTRAN libraries compiled via GFORTRAN.

I followed the instructions under Calling FORTRAN from Root/C++ Makefile question

After compilation of the C++ script under root I get the following error:

C:\root\macros\libmyf77.so : fatal error LNK1107: invalid or corrupt file: cannot read at 0x420

So somehow the fortran library has been wrongly compiled. However, I tried all suggested possibilities. I would be very thankful for some advice.

Best regards,
Ralph

Searching on the web for similar error it looks like this happens when
the fortran environment is not properly installed.
Are you able to make a small “Hello World” example on your machine ?
just a simple Fortran test to see if your fortran environment is correct ?

      PROGRAM MAIN
      PRINT*, "Hello World"
      END

Hi Ralph,

[quote=“Sinkus”]C:\root\macros\libmyf77.so : fatal error LNK1107: invalid or corrupt file: cannot read at 0x420

So somehow the fortran library has been wrongly compiled. However, I tried all suggested possibilities. I would be very thankful for some advice.[/quote]Indeed, the “.so” files are Linux binaries. You need to recompile your fortran library natively on a Windows machine, to get the proper .lib and/or .dll binaries, compatible with Windows…

Cheers, Bertrand.

Dear Bertrand,
many thanks for the hint. So I solved it and here is the manual (not straightforward):

  1. Compile your FORTRAN code myf77.f to get an object file

gfortran –c myf77.f

  function myf77(arg1,arg2)
  integer arg1
  double precision arg2,myf77
  myf77 = arg1*sqrt(arg2)
  print *, 'arg1=',arg1,'  arg2=',arg2, '  myf77=',myf77
  end
  1. Create a FORTRAN DLL from the object file

gfortran –shared –o myf77.dll myf77.o

  1. prepare a myf77.def file using an editor
    This file lists all the routines which shall be accessible from the outside world

LIBRARY myf77.dll
EXPORTS
myf77_
myf77__

  1. convert the DLL into a lib via the VC++ lib program

lib /machine:i386 /def:myf77.def

this creates the myf77.lib file

  1. announce the existence of the routine in the main program

#define myf77 myf77_
extern “C” double myf77(int *arg1, double *arg2);

  1. Use pointers to transfer data to the subroutine in the main program

int *i;
double *d;

i = (int*) malloc(1*sizeof(int));
*i = 23;

d = (double*) malloc(1*sizeof(double));
*d = 3.1415;

double res = myf77(i, d);
printf(“res=%g\n”,res);

  1. Add the myf77.lib to the linker dependencies

  2. Compile and it works :slight_smile:
    

Best

Ralph