importing interface module procedure from fortran

2019-08-28 06:13发布

问题:

How should I import a fortran interface into C using extern?

Suppose I have the following fortran module:

!swapper module
module swapper
   interface swap
      module procedure swap_r, swap_i, swap_c
   end interface
contains
    !subroutine implementations here:
    !swap_r takes two double precision as argument
    !swap_i takes two integers as argument
    !swap_c takes two characters as argument
end module swapper

Then can I just do in C, the following?

extern "C" void __swapper_MOD_swap(double*, double*)
extern "C" void __swapper_MOD_swap(int*, int*)
extern "C" void __swapper_MOD_swap(char*, char*)

Alternatively, if I promise to call swap with only double precision numbers, may I exclusively do this?

extern "C" void __swapper_MOD_swap(double*, double*)

回答1:

It looks like you are actually using C++. But first lets answer for C or C-style C++:

No, you cannot do

extern "C" void __swapper_MOD_swap(double*, double*)

you cannot do it for three different types of arguments, you cannot do it even for a single type of arguments.

There actually should not be any __swapper_MOD_swap in the library in the first place.

What Fortran does is that it keeps an interface (which is just a description how to call something) for the three specific subroutines swap_r, swap_i, swap_c and lets you call it by name swap.

But there is NO actual subroutine swap in the module!!! Fortran will just let you call those three specifics under a different name, that's all.

There is no way how to call those functions from C like a generic. C does not have this type of generics! (It does have some functions which operate on any type using void*).


In C++ you can actually make generics which are specialized for different types and you can call the Fortran procedures as a generic, but you have to tell that to C++ yourself! You can make a template and manually specialize this template to call the appropriate extern "C" functions.

For an example see my header https://github.com/LadaF/PoisFFT/blob/master/src/poisfft.h where I make a C++ class which is linked to an extern "C" struct and some extern "C" functions which are however all implemented in Fortran.


Finally, DO NOT use the __swapper_MOD_ symbols. Create some Fortran binding using bind(C,name="some_name") and call some_name through extern "C", because different Fortran compilers DO use different name mangling schemes.