Pregunta

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.

¿Fue útil?

Solución

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top