Fortran - 无法从主机作用域单元导入`c_char`

时间:2018-03-13 14:04:25

标签: compiler-errors compilation fortran gfortran

我有一个用Fortran(固定格式源)编写的程序,我需要将它与用C ++编写的库链接。我的程序和库都使用MPI,所以我使用的是mpif90编译器。我有一个包含对库的绑定的短接口interface.inc,所以我可以在我的程序中调用它的函数。

问题是,我无法编译我的代码,因为一个奇怪的错误:

/projects/test/meric/include/meric.inc:11:22:

   IMPORT :: C_CHAR
                  1
Error: Cannot IMPORT ‘c_char’ from host scoping unit at (1) - does not exist.
/projects/test/meric/include/meric.inc:12:21:

   CHARACTER(KIND=C_CHAR), DIMENSION(*) :: reg_name
                 1
Error: Parameter ‘c_char’ at (1) has not been declared or is a variable, which does not reduce to a constant expression
header.h:9:19:

   implicit none
               1
Error: IMPLICIT NONE statement at (1) cannot follow INTERFACE statement at (2)
x_solve.f:51:44:

   INTERFACE_START( x_slv , "x_solve" )

我们可以在以下代码片段中看到,C_CHAR类型应使用ISO_C_BINDINGS模块提供:

程序主:

       program BT
       USE, INTRINSIC :: ISO_C_BINDING
       include 'header.h'
#include "interface.inc"

interface.h:

  INTERFACE
  SUBROUTINE FuncA() BIND(c,NAME='FuncA')
  END SUBROUTINE FuncA
  SUBROUTINE FuncB(param_name) BIND(c,NAME='FuncB')
  IMPORT :: C_CHAR
  CHARACTER(KIND=C_CHAR), DIMENSION(*) :: param_name
  END SUBROUTINE FuncB
  END INTERFACE

header.h

c---------------------------------------------------------------------
c---------------------------------------------------------------------
c
c  header.h
c
c---------------------------------------------------------------------
c---------------------------------------------------------------------

      implicit none

c---------------------------------------------------------------------
c The following include file is generated automatically by the
c "setparams" utility. It defines 
c      problem_size:  maximum overall grid size
c      dt_default:    default time step for this problem size if no
c                     config file
c      niter_default: default number of iterations for this problem size
c---------------------------------------------------------------------

      include 'npbparams.h'

      integer           aa, bb, cc, BLOCK_SIZE
      parameter        (aa=1, bb=2, cc=3, BLOCK_SIZE=5)

      integer           npb_verbose
      double precision  elapsed_time
      logical           timeron
      common /global/   elapsed_time, npb_verbose, timeron

      double precision  tx1, tx2, tx3, ty1, ty2, ty3, tz1, tz2, tz3, 
     >                  dx1, dx2, dx3, dx4, dx5, dy1, dy2, dy3, dy4, 
     >                  dy5, dz1, dz2, dz3, dz4, dz5, dssp, dt, 
     >                  ce(5,13), dxmax, dymax, dzmax, xxcon1, xxcon2, 
     >                  xxcon3, xxcon4, xxcon5, dx1tx1, dx2tx1, dx3tx1,
     >                  dx4tx1, dx5tx1, yycon1, yycon2, yycon3, yycon4,
     >                  yycon5, dy1ty1, dy2ty1, dy3ty1, dy4ty1, dy5ty1,
     >                  zzcon1, zzcon2, zzcon3, zzcon4, zzcon5, dz1tz1, 
     >                  dz2tz1, dz3tz1, dz4tz1, dz5tz1, dnxm1, dnym1, 
     >                  dnzm1, c1c2, c1c5, c3c4, c1345, conz1, c1, c2, 
     >                  c3, c4, c5, c4dssp, c5dssp, dtdssp, dttx1,
     >                  dttx2, dtty1, dtty2, dttz1, dttz2, c2dttx1, 
     >                  c2dtty1, c2dttz1, comz1, comz4, comz5, comz6, 
     >                  c3c4tx3, c3c4ty3, c3c4tz3, c2iv, con43, con16

      common /constants/ tx1, tx2, tx3, ty1, ty2, ty3, tz1, tz2, tz3,
     >                  dx1, dx2, dx3, dx4, dx5, dy1, dy2, dy3, dy4, 
     >                  dy5, dz1, dz2, dz3, dz4, dz5, dssp, dt, 
     >                  ce, dxmax, dymax, dzmax, xxcon1, xxcon2, 
     >                  xxcon3, xxcon4, xxcon5, dx1tx1, dx2tx1, dx3tx1,
     >                  dx4tx1, dx5tx1, yycon1, yycon2, yycon3, yycon4,
     >                  yycon5, dy1ty1, dy2ty1, dy3ty1, dy4ty1, dy5ty1,
     >                  zzcon1, zzcon2, zzcon3, zzcon4, zzcon5, dz1tz1, 
     >                  dz2tz1, dz3tz1, dz4tz1, dz5tz1, dnxm1, dnym1, 
     >                  dnzm1, c1c2, c1c5, c3c4, c1345, conz1, c1, c2, 
     >                  c3, c4, c5, c4dssp, c5dssp, dtdssp, dttx1,
     >                  dttx2, dtty1, dtty2, dttz1, dttz2, c2dttx1, 
     >                  c2dtty1, c2dttz1, comz1, comz4, comz5, comz6, 
     >                  c3c4tx3, c3c4ty3, c3c4tz3, c2iv, con43, con16

      double precision cuf(0:problem_size),  q(0:problem_size),
     >                 ue(0:problem_size,5), buf(0:problem_size,5)
      common /work_1d/ cuf, q, ue, buf
!$OMP THREADPRIVATE(/work_1d/)

      integer   max_zones
      parameter (max_zones=x_zones*y_zones)
      integer   x_start(x_zones), x_end(x_zones), x_size(x_zones),
     >          y_start(y_zones), y_end(y_zones), y_size(y_zones),
     >          iz_west (max_zones), iz_east (max_zones),
     >          iz_south(max_zones), iz_north(max_zones)
      common /zones/ x_start, x_end, x_size, y_start, y_end, y_size,
     >               iz_west, iz_east, iz_south, iz_north

      dimension start1(max_zones), start5(max_zones),
     $          qstart_west (max_zones), qstart_east (max_zones),
     $          qstart_south(max_zones), qstart_north(max_zones)
      common /array_start/ start1, start5, qstart_west, qstart_east,
     $                     qstart_south, qstart_north, qoffset


c-----------------------------------------------------------------------
c   Timer constants
c-----------------------------------------------------------------------
      integer t_rhsx,t_rhsy,t_rhsz,t_xsolve,t_ysolve,t_zsolve,
     >        t_rdis1,t_rdis2,t_add,
     >        t_rhs,t_last,t_total
      parameter (t_total = 1)
      parameter (t_rhsx = 2)
      parameter (t_rhsy = 3)
      parameter (t_rhsz = 4)
      parameter (t_rhs = 5)
      parameter (t_xsolve = 6)
      parameter (t_ysolve = 7)
      parameter (t_zsolve = 8)
      parameter (t_rdis1 = 9)
      parameter (t_rdis2 = 10)
      parameter (t_add = 11)
      parameter (t_last = 11)

meric.inc

  USE, INTRINSIC :: ISO_C_BINDING

  INTERFACE
  SUBROUTINE MERIC_Init() BIND(c,NAME='MERIC_Init')
  END SUBROUTINE MERIC_Init
  SUBROUTINE MERIC_Close() BIND(c,NAME='MERIC_Close')
  END SUBROUTINE MERIC_Close
  SUBROUTINE MERIC_IgnoreStart() BIND(c,NAME='MERIC_IgnoreStart')
  END SUBROUTINE MERIC_IgnoreStart
  SUBROUTINE MERIC_IgnoreStop() BIND(c,NAME='MERIC_IgnoreStop')
  END SUBROUTINE MERIC_IgnoreStop
  SUBROUTINE MERIC_MeasureStart(reg_name) BIND(c,NAME='MERIC_MeasureStart')
  IMPORT :: C_CHAR
  CHARACTER(KIND=C_CHAR), DIMENSION(*) :: reg_name
  END SUBROUTINE MERIC_MeasureStart
  SUBROUTINE MERIC_MeasureStop() BIND(c,NAME='MERIC_MeasureStop')
  END SUBROUTINE MERIC_MeasureStop
  END INTERFACE

您知道吗,为什么C_CHAR未从ISO_C_BINDINGS导入?

然后我尝试了另一种编译程序的方法:

程序主:

       module tmp
#include "interface.inc"
       end module tmp

       program BT
c---------------------------------------------------------------------
       USE tmp
#include "header.h"

但现在,代码返回以下错误:

header.h:9:19:

       implicit none
                   1
Error: IMPLICIT NONE statement at (1) cannot follow INTERFACE statement at (2)

提到的implicit none语句位于header.h的开头,但接口本身封装在程序外的模块中。

导致冲突的原因是什么?

当我从implicit none删除header.h语句时,程序会编译,但我想了解,这里发生了什么。

修改

添加了源代码。

1 个答案:

答案 0 :(得分:0)

有意在meric.inc中发生错误,并且该文件未在问题中列出。此外,还显示了interface.h的来源,但所包含的文件是' header.h and interface.inc`。

有几种方法可以通过错误陈述出现的平局隐藏C_CHAR

  1. 它可以位于接口主体内的接口主体中。该外部接口主体可能认为它不需要C_CHAR,因此不能导入它,但内部接口主体不能导入它。
  2. 如果包含文件中某处有USE语句,则为

    use ISO_C_BINDING, only: surprise_me => C_CHAR
    
  3. 然后,这隐藏了C_CHAR的名称,即使该名称可以在没有上述声明生效的情况下访问。