数组和标量的 Fortran 到 C 接口
Fortran to C interface for arrays and scalars
我正在学习如何将 Fortran 与 C 接口。我编写了简单的 C 代码,将所有数组值设置为 1:
#include <stdlib.h>
void cset( int *array, int size ) {
for (size_t i = 0; i < size; i++) {
array[i] = 1;
}
return;
}
我想编写一个 Fortran 接口来处理数组(任意维度)和标量。
我的 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
这适用于标量和一维数组。
为什么界面不适用于 cset( array2d, size(array2d) )
,但适用于 cset_array( array2d, size(array2d) )
或 call 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)
有没有更'proper'的方式来写这样的接口?以这种方式传递标量是否可以?
谢谢你和亲切的问候。
相关:
Passing a two dimentional array from Fortran to C
您不能使用假定大小的数组 (dimension(*)
) 来允许将相同的特定过程用于多个等级(维度)的数组。由于 TKR 规则(类型、种类、等级),所有特定程序仅适用于一个等级。如果您尝试将不同级别的数组传递给通用过程,即使可以将数组直接传递给特定过程,特定过程也不会被识别。
我知道的唯一解决方案是为每个等级分别制作特定的程序接口。
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
相同
我正在学习如何将 Fortran 与 C 接口。我编写了简单的 C 代码,将所有数组值设置为 1:
#include <stdlib.h>
void cset( int *array, int size ) {
for (size_t i = 0; i < size; i++) {
array[i] = 1;
}
return;
}
我想编写一个 Fortran 接口来处理数组(任意维度)和标量。
我的 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
这适用于标量和一维数组。
为什么界面不适用于 cset( array2d, size(array2d) )
,但适用于 cset_array( array2d, size(array2d) )
或 call 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)
有没有更'proper'的方式来写这样的接口?以这种方式传递标量是否可以?
谢谢你和亲切的问候。
相关:
Passing a two dimentional array from Fortran to C
您不能使用假定大小的数组 (dimension(*)
) 来允许将相同的特定过程用于多个等级(维度)的数组。由于 TKR 规则(类型、种类、等级),所有特定程序仅适用于一个等级。如果您尝试将不同级别的数组传递给通用过程,即使可以将数组直接传递给特定过程,特定过程也不会被识别。
我知道的唯一解决方案是为每个等级分别制作特定的程序接口。
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