3

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

这是我的文件 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 论坛:实际上我从一开始就错了。与我的想法相反,不需要使用 dll_export 语句,它甚至引入了问题:没有它,编译器会附加下划线。默认情况下会导出所有符号,如在 gfortran 中。所以正确的代码很简单:

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

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


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

4

0 回答 0