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

How to make compile a Fortran program that calls a C function?

pr0crastin8r
Beginner
490 Views
Hey all,

I am on Windows XP running the Intel Visual Fortran Compiler Version 11.1.065 and the native C compiler in Visual Studio 2008. I am having issues with the magling of symbols between the object files of the two languages that result in unresolved externals in the linker. I was wondering if there are any changes I need to make to my code or command line options I can set on the compiler to make this work. Here is my code:

cshare.f:

[fortran]      program flagtest
         
         logical :: flagSet
         character*32 yes_msg
         character*32 no_msg
         character*32 start_msg
         integer millis

         millis = 1000
         yes_msg = 'Go!'
         no_msg = 'No flag detected, sleeping...'
         start_msg = 'Starting up...'
10       format(a32)


         write(*,10) start_msg

         do while(1==1)
            inquire(FILE="flag", EXIST=flagSet)
            if(flagSet) then
               write(*,10) yes_msg
               call system('DEL flag.txt')
            else
               write(*,10) no_msg
               call csleep(millis)
            endif
         end do
         stop
      end[/fortran]


csleep.c

[cpp]#include 
#include 

int csleep_(int *millis)
{	
   Sleep(*millis);
   printf("What a good night's sleep! A whole %d milliseconds!\n",*millis);
   return(0);
}[/cpp]


Commands:

on Visual Studio command line:
cl -c csleep.c

on ifort command line:
ifort /Qvc9 /c cshare.f
ifort /Qvc9 csleep.obj cshare.obj /exe:csleep


output:
-out:csleep.exe
-subsystem:console
csleep.obj
cshare.obj
cshare.obj : error LNK2019: unresolved external symbol _CSLEEP referenced in function _MAIN__
csleep.exe : fatal error LNK1120: 1 unresolved externals


Can anyone tell me what I need to do differently?

Thanks!
0 Kudos
3 Replies
mecej4
Honored Contributor III
490 Views
You may either look up the naming conventions in the Fortran documentation, or let the compiler do it for you in steps.

If you compile the Fortran part stand-alone, you get the message from the linker:
[bash]unresolved external symbol _CSLEEP[/bash]
Therefore, the name of the C function should be "CSLEEP", not "csleep" and no extra underscores are needed. Secondly, subroutines do not return values and cannot have a type. Therefore, the return type of the C function should be void, not int.

With these changes, and compiling with consistent options, I get

[bash]Starting up...
No flag detected, sleeping...
What a good night's sleep! A whole 1000 milliseconds!
No flag detected, sleeping...
What a good night's sleep! A whole 1000 milliseconds!
No flag detected, sleeping...
...[/bash]

0 Kudos
pr0crastin8r
Beginner
490 Views
Thank you! That worked!
0 Kudos
TimP
Honored Contributor III
490 Views
There are a perhaps bewildering number of options discussed in the ifort docs. In the case at hand, I don't see a reason for avoiding the portable method, which is the USE ISO_C_BINDING method.
0 Kudos
Reply