我有一个用 Fortran(固定格式源)编写的程序,我需要将它与用 C++ 编写的库链接。我的程序和库都使用 MPI,所以我使用的是 mpif90 编译器。我有一个简短的界面interface.inc
包含到库的绑定(bind),所以我可以在我的程序中调用它的函数。
问题是,由于一个奇怪的错误,我无法编译我的代码:
/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
头文件.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
的开头,但接口(interface)本身被封装在程序外的模块中。是什么导致了冲突?
当我删除
implicit none
来自 header.h
的声明,然后程序编译,但我想了解,这里发生了什么。编辑
添加了源代码。
最佳答案
有趣的是错误发生在 meric.inc
并且该文件未在问题中列出。也是interface.h
的来源已显示,但包含的文件是 'header.h and
接口(interface).inc`。
有几种方法C_CHAR
可以通过出现错误语句的关系隐藏。
C_CHAR
所以不要导入它,但是内部接口(interface)主体没有它可用于导入。 USE
包含文件中某处的语句use ISO_C_BINDING, only: surprise_me => C_CHAR
然后这隐藏了
C_CHAR
的名称即使在没有上述声明的情况下可以访问该名称。
关于compiler-errors - Fortran - 无法从主机范围单元导入 `c_char`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49258241/