我正在学习如何将 Fortran 与 C 接口(interface)。我编写了简单的 C 代码,将所有数组值设置为 1:
#include <stdlib.h>
void cset( int *array, int size ) {
for (size_t i = 0; i < size; i++) {
array[i] = 1;
}
return;
}
我想编写一个适用于数组(任何维度)和标量的 Fortran 接口(interface)。
我的 Fortran 代码:
program main
use iso_c_binding
implicit none
interface cset
! Interface for arrays.
subroutine cset_array( array, size ) bind( C, NAME="cset" )
import
integer(C_INT), intent(inout) :: array(*)
integer(C_INT), value, intent(in) :: size
end subroutine cset_array
! Interface for scalars. NOTE: Fortran values are passed by reference (so this should work)
subroutine cset_scalar( scalar, size ) bind( C, NAME="cset" )
import
integer(C_INT), intent(inout) :: scalar
integer(C_INT), value, intent(in) :: size
end subroutine cset_scalar
end interface cset
integer :: scalar = 0
integer :: array(3) = 0
integer :: array2d(3,3) = 0
call cset( scalar, 1 )
print *, scalar
call cset( array, size(array) )
print *, array
! Does not work???
! call cset( array2d, size(array2d) )
! But works for
call cset_array( array2d, size(array2d) )
! OR call cset( array2d(1,1), size(array2d) )
print *, array2d
end program main
这适用于标量和一维数组。
为什么该接口(interface)不适用于 cset( array2d, size(array2d) )
,但适用于 cset_array( array2d, size(array2d) )
或 调用cset( array2d(1,1), size(array2d) )
?在第一种情况下,我收到以下错误(gfortran-7.4):
call cset( array2d, size(array2d) )
1
Error: There is no specific subroutine for the generic ‘cset’ at (1)
有没有更“正确”的方式来编写这样的界面?以这种方式传递标量可以吗?
谢谢您并致以亲切的问候。
相关:
Passing a two dimentional array from Fortran to C
Passing both scalars and arrays (of any dimensions) from Fortran to C
最佳答案
您不能使用假定大小的数组 (dimension(*)
) 来允许将相同的特定过程用于多个等级(维度)的数组。由于 TKR 规则(类型、种类、等级),所有具体程序仅适用于一个等级。如果您尝试将不同等级的数组传递给通用过程,即使可以直接将数组传递给特定过程,特定过程也将无法被识别。
我所知道的唯一解决方案是为每个等级分别制作特定的程序接口(interface)。
subroutine cset_array1( array, size ) bind( C, NAME="cset" )
import
integer(C_INT), intent(inout) :: array(*)
integer(C_INT), value, intent(in) :: size
end subroutine cset_array1
subroutine cset_array2( array, size ) bind( C, NAME="cset" )
import
integer(C_INT), intent(inout) :: array(1,*)
integer(C_INT), value, intent(in) :: size
end subroutine cset_array2
如果你只有一个可以接受任何东西的过程,比如 MPI 过程,那么可以使用特定于编译器的
!$GCC attributes no_arg_check
或与相同!$DEC
关于c - 用于数组和标量的 Fortran 到 C 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59660602/