在默认类型和 C 互操作类型之间转换 Fortran 字符和逻辑数组

Posted

技术标签:

【中文标题】在默认类型和 C 互操作类型之间转换 Fortran 字符和逻辑数组【英文标题】:Converting Fortran character and logical arrays between default and C-interoperable kinds 【发布时间】:2021-08-27 09:13:08 【问题描述】:

我在 C 接口中封装了一些遗留的 F77 代码(我无法更改)。假设遗留代码有

subroutine foo(s, l)
  character*10  s
  logical       l(10)
  …

我正在编写一个小的 F2008 包装器 foo_wrapper,它打算通过 ISO_C_BINDING 公开一个与 C 兼容的接口,进行任何必要的类型转换,调用 foo,最后再次进行类型转换。我的理解是我应该从

subroutine foo_wrapper(c_s, c_l) bind(C, name="foo_wrapper")
  use ISO_C_BINDING, only: C_CHAR, C_BOOL
  character(kind=C_CHAR, len=1), dimension(10) :: c_s
  logical(kind=C_BOOL)                            c_l(10)
  …

但是我实际上如何将c_s 转换为character*10,以及将c_l 转换为logical(并在通话后返回)?

【问题讨论】:

从逻辑上讲,您是在询问简单地更改种类类型参数(如l=logical(c_l); ...; c_l=logical(l, kind=c_bool))还是其他? 我很难找到问题所在,您不能直接复制到适当类型和种类的变量中然后再退出吗? @IanBush:复制底层内存?不,我不保证c_s 具有与foo 的第一个参数相同的内存表示(同样适用于c_l 和第二个参数)。使用类型转换复制循环中的每个元素?是的,这正是我想做的。如何? :-) @francescalus:我不确定我是否理解你的问题,你能详细说明一下吗?顺便说一句,感谢您的编辑 - 它大大改进了标题! 是的,Fortran 端没有什么是指针。 【参考方案1】:

具有默认种类参数的类型不一定无法互操作。互操作性基于种类编号,而不是声明中kind=c_kind 的具体使用。如果种类编号(如果有,长度类型参数)匹配,则类型相同。

对具有相同内在类型"converts"的表达式的内在类型变量进行内在赋值,必要时提供种类类型参数。

复制输入/复制输出机制类似于

<type>(kind=f_kind) f
<type>(kind=c_kind) c

c = f
call foo(c)
f = c

其中fc 也可以是形状相同的数组。

这总是复制。如果您想更花哨,可以使用answer 中的技术到相关问题,使用指针,仅在默认类型和可互操作类型不同时进行复制。

对于实数和整数内在类型,人们可能期望默认类型参数(或 real(kind=c_double) 的双精度参数)是可互操作的。默认逻辑是less likely to be interoperable:Fortran 的默认逻辑具有与默认实数相同的存储大小,这可能不是 C 的布尔类型所具有的。

字符自然也可能具有可互操作的默认种类,但您还必须担心标量和数组之间的转换。同样,复制/关联链接答案中的技术与种类转换同时处理此问题。

考虑程序

  use, intrinsic :: iso_c_binding
  implicit none
  
  print 1, "float", KIND(0e0)==c_float
  print 1, "double", KIND(0d0)==c_double
  print 1, "int", KIND(1)==c_int
  print 1, "char", KIND('')==c_char
  print 1, "bool", KIND(.TRUE.)==c_bool

1 format (A,":",T10,L1)
end program

【讨论】:

以上是关于在默认类型和 C 互操作类型之间转换 Fortran 字符和逻辑数组的主要内容,如果未能解决你的问题,请参考以下文章

C 和 C++ 中类型的互操作性

DateTimeHelper日期类型与字符串互转以及日期对比相关操作

go strconv

Swift中使用Cocoa数据类型,有哪些操作?

Go基础系列:数据类型转换(strconv包)

python编码类型互转总结