gpt4 book ai didi

R 使用字符参数调用 Fortran 子例程

转载 作者:行者123 更新时间:2023-12-05 03:57:46 26 4
gpt4 key购买 nike

如何从 R 中调用带有字符参数的 Fortran 子例程?尽管我能够使用 double 参数调用 Fortran 子例程,但我这样做的尝试并没有奏效。对于 Fortran 代码

subroutine square(x,x2)
double precision, intent(in) :: x
double precision, intent(out) :: x2
x2 = x*x
end subroutine square

subroutine pow(c,x,y)
character (len=255), intent(in) :: c
double precision, intent(in) :: x
double precision, intent(out) :: y
if (c == "s") then
y = x**2
else if (c == "c") then
y = x**3
else
y = -999.0d0 ! signals bad argument
end if
end subroutine pow

和R代码

dyn.load("power.dll") # dll created with gfortran -shared -fPIC -o power.dll power.f90
x <- 3.0
foo <- .C("square_",as.double(x),as.double(0.0))
print(foo)
bar <- .C("pow_",as.character("c"),as.double(x),as.double(0.0))
print(bar)

来自

的输出
C:\programs\R\R-3.6.1\bin\x64\rterm.exe --vanilla --slave < xcall_power.r

[[1]]
[1] 3

[[2]]
[1] 9

[[1]]
[1] "c"

[[2]]
[1] 3

[[3]]
[1] -999

最佳答案

当您使用 .C 时要调用 Fortran 子例程,调用会将字符参数视为 C 风格 char ** .这与 character(len=255) 类型的 Fortran 虚拟参数不兼容。 .

您有两种“简单”的方法可用:

  • 修改 Fortran 子例程以接受类似 char ** 的参数
  • 使用.Fortran而不是 .C

修改 Fortran 子例程以使用 C 与 char ** 的互操作性最好是一个新问题的主题(因为它的广度并且不特定于您的 R 问题)。一般来说,我更喜欢编写在 R 中使用的 Fortran 过程,因为它公开了 C 互操作接口(interface)和 .C.Call .通过以下内容,您也可能得出该结论。

即使是 R 文档也不乐观地使用 .Fortran 传递字符参数:

‘.Fortran’ passes the first (only) character string of a character vector as a C character array to Fortran: that may be usable as ‘character*255’ if its true length is passed separately. Only up to 255 characters of the string are passed back. (How well this works, and even if it works at all, depends on the C and Fortran compilers and the platform.)

您需要阅读有关参数传递约定的文档,例如 for gfortran (请查阅相应版本,因为这些约定可能会更改)。

.Fortran和 gfortran 然后使用不可与 C 互操作的过程,您将需要将“隐藏”参数传递给指定字符参数长度的 Fortran 过程。对于显式长度字符(恒定长度,甚至长度为 1 或不是)和假定长度字符都是如此。

对于版本 7 之前的 gfortran,此隐藏参数是 (R) 类型整数。使用 pow的问题,或者假设长度的论点,我们可以尝试类似的东西

bar <- .Fortran("pow", as.character("c"), as.double(x), as.double(0.0), 255L)

但是请注意,这不是标准的并且本质上不可移植。事实上,正如 janneb 评论和上面链接的文档所述,如何将这个隐藏参数从 R 传递到 gfortran 编译过程取决于 version of gfortran used .使用 255L最后可能不会在 gfortran 7 之外工作。相反,您需要将隐藏参数作为与 integer(c_size_t) 匹配的内容传递。 (可能是 64 位整数)。对于 gfortran 以外的编译器,您可能需要做一些完全不同的事情。

最好使用 C 互操作过程,其参数可与 char ** 互操作。 (使用 .C )或 char [] (使用 .Fortran )。就像我说的,在这里选择第一个选项是值得的,因为它留下了更大的灵 active (比如更长的字符、更多的可移植性和更多的字符参数)。

关于R 使用字符参数调用 Fortran 子例程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58358837/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com