将接口模块过程从fortran导入C

时间:2017-06-14 00:42:07

标签: c fortran language-interoperability

如何使用interface将强奸extern导入C?

假设我有以下fortran模块:

!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

那么我可以在C中做以下吗?

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

或者,如果我保证只用双精度数字来呼叫swap,我可以专门做这个吗?

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

1 个答案:

答案 0 :(得分:1)

看起来你实际上在使用C ++。但首先让我们回答C或C风格的C ++:

不,你做不到

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

你不能为三种不同类型的参数做到这一点,即使对于单一类型的参数也不能这样做。

首先,库中不应该有任何__swapper_MOD_swap

Fortran所做的是它为三个特定的子例程swap_r, swap_i, swap_c保留一个接口(这只是一个如何调用某些内容的描述),并允许您按名称swap调用它。

但是模块中没有实际的子例程swap !!! Fortran会让你用不同的名称来调用这三个细节,这就是全部。

如何从C中调用这些函数就像通用一样。 C没有这种类型的泛型!(它确实有一些使用void*在任何类型上运行的函数。)

在C ++中,您实际上可以创建专门用于不同类型的泛型,并且可以将Fortran过程称为泛型,但您必须自己告诉C ++!您可以创建模板并手动专门化此模板以调用相应的extern "C"函数。

有关示例,请参阅我的标题https://github.com/LadaF/PoisFFT/blob/master/src/poisfft.h,其中我创建了一个C ++类,该类链接到extern "C" struct和一些extern "C"函数,但这些函数都在Fortran中实现。

最后,请勿使用__swapper_MOD_符号。使用bind(C,name="some_name")创建一些Fortran绑定并通过some_name调用extern "C",因为不同的Fortran编译器使用不同的名称修改方案。