在默认类型和 C 互操作类型之间转换 Fortran 字符和逻辑数组
Converting Fortran character and logical arrays between default and C-interoperable kinds
我在 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
(并在调用后返回)?
具有默认种类参数的类型不一定不能互操作。互操作性基于种类编号,而不是声明中 kind=c_kind
的具体使用。如果种类数(如果有的话,长度类型参数)匹配则类型相同。
对同一内部类型表达式的内部类型变量进行内部赋值"converts"必要的种类类型参数。
一个copy-in/copy-out机制就像
<type>(kind=f_kind) f
<type>(kind=c_kind) c
c = f
call foo(c)
f = c
其中f
和c
也可以是形状相同的数组。
这总是复制。如果你想更花哨,你可以使用 answer 中的技术来解决相关问题,使用指针,仅当默认类型和可互操作类型不同时才进行复制。
对于实数和整数内部类型,人们可能期望默认种类参数(或 real(kind=c_double)
的双精度)是可互操作的。默认逻辑是 less likely to be interoperable:Fortran 的默认逻辑具有与默认实数相同的存储大小,这可能不是 C 的布尔类型所具有的。
字符自然也可能有可互操作的默认种类,但你还得担心标量和数组之间的转换。同样,copy/associate 链接答案中的技术与类型转换同时处理此问题。
考虑该计划
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 接口中封装了一些遗留的 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
(并在调用后返回)?
具有默认种类参数的类型不一定不能互操作。互操作性基于种类编号,而不是声明中 kind=c_kind
的具体使用。如果种类数(如果有的话,长度类型参数)匹配则类型相同。
对同一内部类型表达式的内部类型变量进行内部赋值"converts"必要的种类类型参数。
一个copy-in/copy-out机制就像
<type>(kind=f_kind) f
<type>(kind=c_kind) c
c = f
call foo(c)
f = c
其中f
和c
也可以是形状相同的数组。
这总是复制。如果你想更花哨,你可以使用 answer 中的技术来解决相关问题,使用指针,仅当默认类型和可互操作类型不同时才进行复制。
对于实数和整数内部类型,人们可能期望默认种类参数(或 real(kind=c_double)
的双精度)是可互操作的。默认逻辑是 less likely to be interoperable:Fortran 的默认逻辑具有与默认实数相同的存储大小,这可能不是 C 的布尔类型所具有的。
字符自然也可能有可互操作的默认种类,但你还得担心标量和数组之间的转换。同样,copy/associate 链接答案中的技术与类型转换同时处理此问题。
考虑该计划
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