【发布时间】:2016-05-18 04:43:12
【问题描述】:
如果这对某些人来说是一个简单的问题,我深表歉意,但我无法在任何地方找到解决方案。 我是 RStudio 初学者,我想从 RStudio 中调用开源 fortran77 模拟程序(其中也有 c 和 c++ 代码)的特定例程。 Fortran 程序使用 Makefiles 进行编译,它会生成许多 .o 目标文件(顺便说一下,我使用的是 Unix)。我在 fortran 中编写了一个包装文件,它与模拟程序一起编译,RStudio 应该使用它来调用 fortran 例程。我生成该包装文件的共享对象文件 .so,如果我在该包装文件中有简单的计算,一切都会很好。我遵循与这篇出色的帖子相同的过程: http://www.r-bloggers.com/fortran-and-r-speed-things-up/
我成功地使用了 dyn.load 和 .Fortran,只要我不调用位于另一个文件(并且对应于其他目标文件和其他 .so 文件)中的子例程,我就会返回结果。当我尝试从包装子例程中调用另一个子例程时,我收到以下错误:
Error in dyn.load("rwrapper.so") :
unable to load shared object '/home/adminuser/ESP-rSource/src/esrubps/rwrapper.so':
/home/adminuser/ESP-rSource/src/esrubps/rwrapper.so: undefined symbol: runit_
runit(不带下划线)是另一个子程序,它位于另一个文件中并且有另一个目标文件。然后我尝试为该 runit 子例程创建第二个共享对象文件,并且我还使用 dyn.load 加载它,但它没有解决问题。我可能在这里做错了什么,但我不知道是什么。我是否需要将所有对象文件转换为 .so 共享对象文件,然后使用 dyn.load 加载每个文件(大约有 100 个 .o 文件)或者“包装器/通信”文件方法是否有效?有没有办法在 fortran 程序和 RStudio 之间建立通信?我在此处粘贴我的 RStudio 脚本仅供参考(请注意,第二个 dyn.load 没有任何区别):
myrwrapper <- function(rrrandom) {
if (!is.loaded('rwrapper')) {
dyn.load("rwrapper.so")
}
if (!is.loaded('esru_lib')) {
dyn.load("./home/adminuser/ESP-rSource/src/lib/esru_lib.so")
}
retvals <- .Fortran("RXCHNGE",icomp = as.integer(2), rCOUPLEVAR = as.numeric(rrrandom))
return(retvals$rCOUPLEVAR)
}
一个简单的解决方案是从两个程序中写入/读取一个文本文件并通过该文件交换数据,但是我的理解是这会使模拟变得非常慢,因为几乎需要打开/关闭一个文件每一步,所以我试图避免这种方法。 感谢您的帮助。
【问题讨论】:
-
既然还没有回应,那我就试着简化一下我上面说的吧。 1. 我使用 RStudio(dyn.load 和 .Fortran)来调用一个 fortran 例程。 2. 当 fortran 例程有简单的内部计算时,我在 RStudio 中收到一个有效的答案 3. 当 fortran 例程调用另一个文件中的另一个子例程时,整个事情都失败了,RStudio 给出一条消息,指出该子例程的名称是一个未定义的符号。它还在子例程名称后放置一个下划线“_”。在同一个文件中调用另一个子例程似乎工作正常。