【问题标题】:Fortran to C interface: Why does doing it right mess everything up? [duplicate]Fortran 到 C 接口:为什么正确操作会搞砸一切? [复制]
【发布时间】:2021-01-29 19:17:28
【问题描述】:

我有很多关于 Fortran/C 接口的知识。在我正在使用的玩具代码中,我使用 C 为 Fortran 分配一个双精度数组(实际上是指针):

double precision, pointer :: arr(:)
type(C_PTR) :: p
integer :: L=50000
p = alloc_for_fortran(L)
call c_f_pointer(p, arr, [L])

alloc_for_fortran 是我编写的一个 C 函数。似乎工作正常。我可以展示它,但我想我会尽量避免不相关的代码,以使这篇文章尽可能简短。)

我有一个简单的 C 函数,它只给出数组的元素:

void examine(double *arr, int *whichone) {
        printf("contents: %lf\n", arr[*whichone-1]);
}

如果我没有在 Fortran 代码中定义接口,这很好用。比如这段代码

arr(1) = 5.3
examine(arr,1)

给出输出:

contents: 5.300000

现在我为examine 定义一个接口,就像我“应该”这样:

interface
subroutine examine(arr, i) bind(C, name="examine")
            use iso_c_binding
            double precision, pointer :: arr(:)
            integer :: i
end subroutine
end interface

现在输出不正确:

contents: 0.000000

谁能告诉我我做错了什么?

【问题讨论】:

  • 从界面中省略“,指针”可能会解决该错误。为什么您认为双精度参数需要指针属性,而整数参数不需要指针属性?一旦我做完晚餐,我可能会添加一个正确的答案,但这可能是主要问题,尽管至少还有一个问题。
  • @IanBush 明智的评论,但它不会改变输出。一样的感谢。顺便说一句,arr 是 Fortran 指针,但 i 只是一个整数。
  • whichonei 是可以按值传递的整数索引,是吗?不需要指针。数组是一个不同的故事,我在 fortran 中一无是处。
  • 那么请展示一个最小的完整示例。
  • @jwdonahue 我的理解是,Fortran 实际上传递的是指针,而不是值。所以接收 C 函数必须取消引用它们。但我完全愿意被更了解的人纠正。

标签: arrays c pointers interface fortran


【解决方案1】:

这就是你的做法。除非您提供 minimal, reproducible example,否则很难说更多。显示的主要错误是尝试将 Fortran 指针传递给 C 指针,当标准 Fortran 参数机制足够时,以及将 C 虚拟参数声明为假定形状数组,当您应该使用假定大小时 C 没有支持更高级的 Fortran 功能

ian@eris:~/work/stack$ cat examine.c
#include <stdio.h>

void examine(double *arr, int *whichone) {
        printf("contents: %lf\n", arr[*whichone-1]);
}
ian@eris:~/work/stack$ cat use_examine.f90
Program use_examine

  Use iso_c_binding, Only : c_double, c_int
  
  Implicit None

  Interface
     Subroutine examine( arr, i ) bind( C, name = 'examine' )
       Use iso_c_binding, Only : c_double, c_int
  
       Implicit None
       Real   ( c_double ), Dimension( * ), Intent( In ) :: arr
       Integer( c_int )                   , Intent( In ) :: i
     End Subroutine examine
  End Interface

  Real( c_double ), Pointer, Dimension( : ) :: a

  Allocate( a( 1:2 ) )
  a( 1 ) = 5.3_c_double

  Call examine( a, 1_c_int )
  
End Program use_examine
ian@eris:~/work/stack$ gcc --version
gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ian@eris:~/work/stack$ gcc -c -Wall -Wextra -std=c99 examine.c
ian@eris:~/work/stack$ gfortran  -c -Wall -Wextra -fcheck=all -std=f2008 use_examine.f90 
ian@eris:~/work/stack$ gfortran use_examine.o examine.o
ian@eris:~/work/stack$ ./a.out
contents: 5.300000

【讨论】:

  • C 可以与假定形状和延迟形状 Fortran 数组互操作
  • 是的,我忘了2018年的新东西——没研究也没用过。将在某个时候进行编辑以更正。
猜你喜欢
  • 2012-06-04
  • 2021-11-02
  • 1970-01-01
  • 2011-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-11
  • 2018-03-15
相关资源
最近更新 更多