Fortran符号不在加载表中(无法在R中调用加载的符号)

时间:2013-09-12 14:46:22

标签: r dll fortran

我正在尝试使用Absoft Pro Fortran 13.0.3,64位构建一个Fortran DLL,用于R,Windows 7 64位。

这是我的文件mycalc.f(这是一个愚蠢的例子,只是为了测试功能):

subroutine mycalcf(a,b,c)
real*8 a,b,c
dll_export mycalcf
c=a+b*b
end

声明dll_export不是标准的,但是在一些Fortran编译器中可以找到(AFAIK也可以在Lahey和CVF中找到它,而英特尔Fortran则有编译器指令)。它只是告诉编译器要导出哪些符号。

我成功编译: af90 -m64 -dll -YDLL_NAMES=LCS mycalc.f -o mycalc.dll

选项-YDLL_NAMES=LCS告诉编译器构建一个带有小写符号的库,这对于R来说似乎更好。

如果我运行dumpbin /exports mycalc.dll,我可以在导出的符号中找到mycalcf,小写,之前或之后没有任何下划线。

现在,从R(64位版本)开始,以下工作:

dyn.load("mycalc.dll")
is.loaded("mycalcf")
.Fortran("mycalcf", a=4, b=5, c=0)

我按照预期返回c = 29.

但是,如果我重新启动R,则以下操作不起作用(请注意我只删除了is.loaded测试):

dyn.load("mycalc.dll")
.Fortran("mycalcf", a=4, b=5, c=0)

我收到错误:Fortran symbol name "mycalcf" not in load table

现在我的问题是:为什么这个测试如此重要?


为了比较,当我尝试使用gfortran而不是Absoft时,我完全没有问题。我使用:gfortran -m64 -shared -o mycalc2.dll mycalc.f进行编译(在注释掉dll_export语句之后,gfortran不需要,甚至不识别)。 然后在R:

dyn.load("mycalc2.dll")
.Fortran("mycalcf", a=4, b=5, c=0)

我得到c = 29,没有错误。

现在,我怀疑gcc链接器做的事情不是由Absoft链接器自动完成的(实际上它是Microsoft的link.exe)。但我没有暗示它可能是什么。

欢迎任何想法!


好的,解决了弗拉基米尔F的一个好问题(见评论)。 实际上,必须将下划线附加到符号名称。由于编译器选项无法执行此操作,因此需要CDEC$指令(请参阅HPIntel文档)。

这里很简单:

      subroutine mycalcf(a,b,c)
CDEC$ attributes alias:'mycalcf_' :: mycalcf
      real*8 a,b,c
      dll_export mycalcf
      c=a+b*b
      end

来自Absoft forum的第二个解决方案:实际上我从一开始就错了。与我的想法相反,不需要使用dll_export语句,它甚至引入了问题:没有它,编译器会附加下划线。默认情况下会导出所有符号,如gfortran中所示。所以正确的代码就是:

      subroutine mycalcf(a,b,c)
      real*8 a,b,c
      c=a+b*b
      end

甚至不需要任何选项来获取小写符号,它也是默认值。


然而,还有一个问题:R函数.Fortran是否总是添加下划线(有没有办法告诉它不要?),如果它总是添加,为什么调用预先调用is.loaded时的工作? R似乎在这里做了一些奇怪的事情。 我尝试跟踪R源代码中的is.loadeddo_isloaded中最多src\main\dotcode.c),但无济于事。

0 个答案:

没有答案