将接口模块程序从 Fortran 导入 C
importing interface module procedure from fortran into C
我应该如何使用 extern
将 fortran interface
导入 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*)
看起来你真的在使用C++。但首先让我们回答 C 或 C-style 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"
函数。
举个例子,看我的 header https://github.com/LadaF/PoisFFT/blob/master/src/poisfft.h 我做了一个 C++ class 链接到 extern "C" struct
和一些 extern "C"
函数但是全部用 Fortran 实现。
最后,不要使用 __swapper_MOD_
符号。使用 bind(C,name="some_name")
创建一些 Fortran 绑定并通过 extern "C"
调用 some_name
,因为不同的 Fortran 编译器确实使用不同的名称修改方案。
我应该如何使用 extern
将 fortran interface
导入 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*)
看起来你真的在使用C++。但首先让我们回答 C 或 C-style 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"
函数。
举个例子,看我的 header https://github.com/LadaF/PoisFFT/blob/master/src/poisfft.h 我做了一个 C++ class 链接到 extern "C" struct
和一些 extern "C"
函数但是全部用 Fortran 实现。
最后,不要使用 __swapper_MOD_
符号。使用 bind(C,name="some_name")
创建一些 Fortran 绑定并通过 extern "C"
调用 some_name
,因为不同的 Fortran 编译器确实使用不同的名称修改方案。