You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R加载gfortran编译的Fortran DLL报错:符号名不在加载表中

解决R调用gfortran编译的Fortran DLL无法识别符号的问题

我之前折腾过R和Fortran交互的坑,看你的情况,核心问题出在你用了Intel Fortran的专属编译指令!DEC$,但实际用gfortran编译——gfortran完全不识别这些指令,导致你的子例程根本没被导出到DLL里,而且你要检查的是子例程名sr1/sr2,不是DLL文件名test,这才是is.loaded返回False的关键。

下面是分步解决方法:

1. 修改Fortran代码,适配gfortran的符号导出规则

把原来的Intel指令换成gfortran支持的bind(C)属性,同时使用iso_c_binding模块保证类型匹配(R和C的类型对应更严谨)。修改后的test.f90代码如下:

use, intrinsic :: iso_c_binding

! Computes the square of a number
subroutine sr1(a, b) bind(C, name='sr1')
    implicit none
    integer(c_int), intent(in) :: a
    integer(c_int), intent(out) :: b
    b = a * a
end subroutine sr1

! Computes the cube of a number
subroutine sr2(x, y) bind(C, name='sr2')
    implicit none
    integer(c_int), intent(in) :: x
    integer(c_int), intent(out) :: y
    y = x * x * x
end subroutine sr2
  • bind(C, name='sr1'):强制子例程使用C风格的符号命名,避免gfortran默认的名字修饰(比如加下划线),让R能准确找到符号。
  • integer(c_int):匹配C语言的int类型,和R中的integer类型对应,避免类型不兼容。
  • intent(in/out):明确参数的输入输出属性,让编译器优化同时避免潜在的内存问题。

2. 重新编译DLL(gfortran命令)

在Windows命令行中执行以下编译命令(确保gfortran在系统PATH里):

gfortran -shared -o test.dll test.f90
  • -shared:告诉编译器生成动态链接库(DLL)而不是可执行文件。
  • 重点:如果你的R是64位版本,必须用64位的gfortran编译,否则会出现加载失败或者位数不匹配的问题。

3. 在R中正确调用子例程

加载DLL后,检查子例程的符号(不是DLL文件名),然后用.Fortran()调用:

# 加载DLL(替换成你的实际文件路径)
dyn.load("C:/your_folder/test.dll")

# 检查子例程是否加载成功
is.loaded("sr1")  # 正常应该返回TRUE
is.loaded("sr2")  # 正常应该返回TRUE

# 调用sr1计算平方
result_sr1 <- .Fortran("sr1", a = as.integer(5), b = integer(1))
cat("5的平方是:", result_sr1$b, "\n")

# 调用sr2计算立方
result_sr2 <- .Fortran("sr2", x = as.integer(4), y = integer(1))
cat("4的立方是:", result_sr2$y, "\n")

# 用完记得卸载DLL
dyn.unload("C:/your_folder/test.dll")
  • 注意:.Fortran()要求参数必须是R的原生类型,所以要用as.integer()把数值转成整数类型,输出参数要预先分配空间(比如integer(1))。

常见排查点

  • 检查gfortran和R的位数是否一致:打开R输入.Machine$sizeof.pointer,如果返回8就是64位,gfortran也要用64位版本(比如MinGW-w64的gfortran)。
  • 确保DLL路径正确:可以用file.exists("your_path/test.dll")检查文件是否存在。
  • 如果还是有问题,用nm test.dll(需要MinGW的nm工具)查看DLL里的导出符号,确认sr1和sr2是否在列表里。

内容的提问来源于stack exchange,提问作者khajlk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:47:17