Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29253 Discussions

Problem with C calling Fortran subroutine embedded in a dynamic library

sallestaing
Beginner
773 Views
Hi all,
I am encountering a problem when running a binary under Linux: symbol lookup error.
The binary is obtained through a C main program which calls a subroutine defines in a fortran shared library.
To build the fortran shared library I used this process:
1- build the fortran source objects
ifort -fPIC -g -c -m64 -heap-arrays -O3 -ipo prog1.f90
ifort -fPIC -g -c -m64 -heap-arrays -O3 -ipo prog2.f90
...
ifort -fPIC -g -c -m64 -heap-arrays -O3 -ipo prog13.f90
ifort -fPIC -g -c -m64 -heap-arrays -O3 -ipo prog14.f90
2- Create the shared library with object files
ifort -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1.0.1 prog1.o prog2.o ...prog13.o prog14.o -lc
3- Export Library Path.
export LD_LIBRARY_PATH=$HOME/Work/myfolder/lib:$LD_LIBRARY_PATH
I've then created a fortran program that reads a fortran subroutine (called fortsub in the next example) defines in the shared library
Here is the program in fortran main.f90:
------------------------
program main
implicit none
! local variables
integer :: m
character(len=128):: finput
! get name of experiment from the argument list and create file names
m=iargc()
finput=' '
if(m.lt.1) then
write(6,*)'use: myprog '
stop
else
call getarg(1,finput) ! get experiment file name
end if
call fortsub(finput)
end
------------------------
Finally I've created the executable using the following :
> ifort -m64 -heap-arrays -O3 -ipo -o bin/myprog main.f90 lib/libmylib.so.1 -I/$HOME/Work/myfolder/modules/
I've tried the obtained binary and it works fine.
However, for distribution purpose, I would like to use a C program instead of a fortran one to call the subroutine.
Here is the C program main.c:
------------------------
#include
#include
extern void fortsub_(char*,long int);
int main(int argc, char *argv[])
{
if ( argc != 2 )
printf("use: %s \\n",argv[0]) ;
else {
long int leng = strlen(argv[1]);
fortsub_(argv[1], leng);
}
return 0;
}
------------------------
I've then compiled it using :
> icc -m64 -heap-arrays -O3 -ipo -o bin/myprog main.c lib/libmylib.so.1 -I/$HOME/Work/myfolder/modules/ -L/opt/intel_fc/10.0.023/lib/ -lifcore -limf

During compilation everything works fine however when I launch the binary I've got the following error:
>./bin/myprog ../test/example1.input
./bin/myprog: symbol lookup error: ./bin/myprog: undefined symbol: fortsub_

I've check the library dependencies as well as the binary and it sounds like nothing missing:
> ldd lib/libmylib.so.1
linux-gate.so.1 => (0xa000000000000000)
libc.so.6.1 => /lib/libc.so.6.1 (0x2000000800730000)
libifport.so.6 => /opt/intel_fc/10.0.023/lib/libifport.so.6 (0x2000000800980000)
libifcore.so.6 => /opt/intel_fc/10.0.023/lib/libifcore.so.6 (0x20000008009dc000)
libimf.so.6 => /opt/intel_cc/10.0.023/lib/libimf.so.6 (0x2000000800bcc000)
libm.so.6.1 => /lib/libm.so.6.1 (0x2000000800ea0000)
libintlc.so.6 => /opt/intel_cc/10.0.023/lib/libintlc.so.6 (0x2000000800f70000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x2000000800fa4000)
libdl.so.2 => /lib/libdl.so.2 (0x2000000800fc4000)
/lib/ld-linux-ia64.so.2 (0x2000000800000000)
libunwind.so.7 => /lib/libunwind.so.7 (0x2000000800fdc000)

> ldd bin/myprog
linux-gate.so.1 => (0xa000000000000000)
libmylib.so.1 => /home/user/Work/myfolder/lib/libmylib.so.1 (0x200000000004c000)
libifcore.so.6 => /opt/intel_fc/10.0.023/lib/libifcore.so.6 (0x2000000000718000)
libimf.so.6 => /opt/intel_fc/10.0.023/lib/libimf.so.6 (0x2000000000908000)
libm.so.6.1 => /lib/libm.so.6.1 (0x2000000000bf0000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x2000000000cc0000)
libc.so.6.1 => /lib/libc.so.6.1 (0x2000000000ce0000)
libdl.so.2 => /lib/libdl.so.2 (0x2000000000f30000)
libunwind.so.7 => /lib/libunwind.so.7 (0x2000000000f48000)
libifport.so.6 => /opt/intel_fc/10.0.023/lib/libifport.so.6 (0x2000000000f94000)
libintlc.so.6 => /opt/intel_fc/10.0.023/lib/libintlc.so.6 (0x2000000000ff0000)
/lib/ld-linux-ia64.so.2 (0x2000000000000000)
Do you have any ideas on what is going on here? Apparently there is a linker error, am I wrong?
It is the first time I try this kind of coupling between fortran and C so any advise will be very helpfull!
Cheers,
Tristan
0 Kudos
3 Replies
eliosh
Beginner
773 Views
We have to guess how fortsub was declared. Did you use BIND ?
0 Kudos
sallestaing
Beginner
773 Views
Hi eliosh,

Thanks for your answer, actually I have defined fortsub
subroutine fortsub(inputfile)
use mod1
use mod2

...

end subroutine fortsub

Do I need to use BIND to define it?
Cheers
Tristan
0 Kudos
eliosh
Beginner
773 Views
Tristan,

My experience with Fortran is quite limited. However, If I understand correctly, the best way would be to use the *standard* C interoperability features of modern Fortran. In this case you should use BIND(C) in your function definition and use *interoperable* inputs/outputs. I also think that your approach is also possible, but you must take care of the different mangling conventions used in C and Fortran. In C, the compiler usually adds an underscore to the end of symbol. In Fortran, if I remember correctly, it is not standardized, you should either search the documentation or run 'nm' on your object file to see what you get.
0 Kudos
Reply