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

向含Rcpp的R包添加Fortran子程序编译报错,求解决方法

问题:R包整合Fortran子程序编译失败

场景重现

原本可正常编译的R包,加入从网上找到的Fortran子程序后,运行devtools::document()时出现编译错误,提示addf_未声明。相关代码如下:

R文件夹代码

#' @export 
testfun<-function() { addc(1,2) + add_Fortran(1,2) }
#' @useDynLib testpac addf
#' @export
add_Fortran <- function(x, y) {
  .Fortran(addf, x, y, numeric(1))[[3]]
}

src文件夹代码

C++文件:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
double addc(double x, double y) {
   return x*y;
}

Fortran文件:

subroutine addf(x, y, answer)
    double precision x, y, answer
    answer = x + y
end

错误信息

from 1mRcppExports.cpp:4:
   1mRcppExports.cpp:28:34: 1;31merror: '1maddf_' was not declared in this scope
      28 |     {"addf", (DL_FUNC) &F77_NAME(1;31maddf), 3},
         |                                  1;31m^~~~
   1mC:/R/include/R_ext/RS.h:104:25: 1;36mnote: in definition of macro '1mF77_CALL'
     104 | # define F77_CALL(x)    1;36mx ## _
         |                         1;36m^
   1mRcppExports.cpp:28:25: 1;36mnote: in expansion of macro '1mF77_NAME'
      28 |     {"addf", (DL_FUNC) &1;36mF77_NAME(addf), 3},
         |                         1;36m^~~~~~~~
   make: *** [C:/R/etc/x64/Makeconf:296: RcppExports.o] Error 1
   ERROR: compilation failed for package 'testC'

解决方案

错误原因是C++编译器编译自动生成的RcppExports.cpp时,找不到Fortran子程序编译后的符号(addf_)。只需添加外部函数声明即可解决:

方法1:在C++代码中添加extern声明

在你的C++文件顶部添加以下代码,告诉编译器addf_是一个外部C风格函数:

extern "C" {
void addf_(double* x, double* y, double* answer);
}

修改后的C++文件如下:

#include <Rcpp.h>
using namespace Rcpp;

// 声明Fortran子程序的C接口
extern "C" {
void addf_(double* x, double* y, double* answer);
}

// [[Rcpp::export]]
double addc(double x, double y) {
   return x*y;
}

方法2:用模块封装Fortran子程序

将Fortran代码改为模块形式,编译器会自动生成更清晰的接口,同时避免符号命名问题:

module add_module
contains
subroutine addf(x, y, answer)
    double precision x, y, answer
    answer = x + y
end subroutine addf
end module add_module

之后同样需要在C++代码中添加extern声明(符号名可能变为add_module_addf_,具体取决于编译器,可通过查看编译后的目标文件确认)。

验证修改

添加声明后,重新运行devtools::document()和devtools::install(),即可正常编译。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 04:50:10