如果对某些人来说这是一个简单的问题我很抱歉,但我无法在任何地方找到解决方案。 我是一个RStudio初学者,我想从RStudio中调用一个开源fortran77模拟程序(其中还有c和c ++代码)的特定例程。 Fortran程序正在使用Makefile进行编译,它会生成许多.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)
}
一个简单的解决方案就是从两个程序中读取/读取文本文件并通过该文件交换数据,但我的理解是,这会使模拟真的很慢,因为需要打开/关闭文件几乎每一步,所以我试图避免这种方法。 谢谢你的帮助。
答案 0 :(得分:0)
这实际上比我想象的容易得多。共享的.so文件是一个新手错误。创建共享文件并将其链接到两个(或更多)目标文件而不是一个时,问题就解决了。例如,如果你有1.F,它调用2.F和相应的1.o和2.o,你应该在创建共享文件时包括这两个文件: gfortran -shared -o 1plus2.so 1.o 2.o