More
on mixing C and Fortran
Consider the following code in C and Fortran:
#include <stdio.h>
void extern ranvec_(double *, int *);
int main()
{
int n = 5;
double a[5];
ranvec_(a, &n);
printf("a = %f, %f, %f, %f, %f\n",
a[0], a[1],
a[2], a[3], a[4]);
return 0;
}
subroutine ranvec(v, n)
integer
:: n
double precision, dimension(n) :: v
call random_seed()
call random_number(v)
end
Giving the obvious commands give problems:
% g95 -c ranvec.f90
% gcc main.c ranvec.o
ranvec.o(.text+0x58): In function `ranvec_':
: undefined reference to `_g95_random_seed'
ranvec.o(.text+0x9d): In function `ranvec_':
: undefined reference to `_g95_random_8'
collect2: ld returned 1 exit status
% gfortran -c ranvec.f90
% gcc main.c ranvec.o
ranvec.o(.text+0x24): In function `ranvec_':
: undefined reference to `_gfortran_random_seed'
ranvec.o(.text+0x54): In function `ranvec_':
: undefined reference to `_gfortran_arandom_r8'
collect2: ld returned 1 exit status
The reason for this meassage is that a libraries containing _g95_random_seed etc. are
missing. These routines reside in Fortran libraries and we have to tell
the C-compiler (the link-phase) to link with the missing libraries.
Here are some examples:
% g95 -c ranvec.f90
% gcc main.c ranvec.o
-L/chalmers/sw/unsup64/g95/lib/gcc-lib/x86_64-unknown-linux-gnu/4.0.3 -lf95
% a.out
a = 0.253645, 0.486569, 0.287456, 0.373990, 0.778394
% gfortran -c ranvec.f90
% gcc main.c ranvec.o -L.
-lgfortran
% a.out
a = 0.126499, 0.082701, 0.330154, 0.401973, 0.248005
To make this work I had to make a soft link to the shared object
under /usr/lib64 (there are
problems with the name of the shared library):
% ln -s /usr/lib64/libgfortran.so.1
libgfortran.so
How do I know what libraries to use? Well, I do not, but it is
reasonable to look in standrad directories, like /usr/lib, /usr/lib64, and install
directories, such as /chalmers/sw/unsup64/g95/lib.
Look for library names containing "fortran". Then try to list the
contents using commands like ar, nm, objdump (depending on type of
library and operating system) and see if you can find the missing
routine.
It may work to compile with gcc and link with the Fortran-compiler.
They may lead to problems with C-libraries, instead.
% gcc -c main.c
% gfortran main.o ranvec.f90
% gcc -c main.c
% g95 main.o ranvec.f90