In my compiler a function named "func" will be renamed as _FUNC@* after compiling in fortran. And if a c code use _stdcall calling convention, then the function name, e.g. Ab, will be renamed as _Ab@* after compiling. So this can lead to a concise method for mixed programming between fortran and c. The following is my code. source1.f90
program main
implicit none
call subprint()
read(*,*)
endprogram
ccode.c
#include <stdio.h>
#ifdef _cplusplus
extern "C" {
#endif
void _stdcall SUBPRINT()
{printf("hello the world\n");}
#ifdef _cplusplus
}
My platform is win 7 and vs2010 is used. Compliler is visual c++. The ccode.c will generate a .lib and the fortran project will use it. And this will run successfully in debug mode. But when I changed the project into release mode, errors would occur. The errors are the main function in Source1.f90 can not find out the _SUBPRINT. Note that I have already generated the .lib in the release mode and add it to the fortran project.
Another method for mixed programming is using _cdecl calling convention. The following codes will run successfully in both debug and release mode.
module abc
interface
subroutine subprint()
!dec$ attributes C,alias:'_subprint'::subprint
end subroutine
end interface
end module
program main
use abc
implicit none
call subprint()
read(*,*)
endprogram
Here is the c code. The default calling convention is just _cdecl.
#ifdef _cplusplus
extern "C" {
#endif
void subprint()
{printf("hello the world\n");}
#ifdef _cplusplus
}
#endif
Why this happened? I put all these codes in the same solution. So the configuration is the same.
First, note that your C function is SUBPRINT
not subprint
, that DOES matter even inside C.
Second, you should use __cplusplus
, not _cplusplus
Third, just use modern Fortran for interoperability with C:
c.cc:
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
void subprint(){
printf("hello the world\n");
}
#ifdef __cplusplus
}
#endif
f.f90:
program main
implicit none
interface
subroutine subprint() bind(C,name="subprint")
end subroutine
end interface
call subprint()
read(*,*)
endprogram
gfortran c.cc f.f90
./a.out
hello the world