gpt4 book ai didi

c - 用于数组和标量的 Fortran 到 C 接口(interface)

转载 作者:行者123 更新时间:2023-12-02 07:57:04 26 4
gpt4 key购买 nike

我正在学习如何将 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com