如何将 Fortran 代码链接到链接到 rcpp 脚本的头文件

How to link Fortran code to a header file that is linked to rcpp script

提问人:elmo 提问时间:6/7/2023 最后编辑:Dirk Eddelbuettelelmo 更新时间:6/7/2023 访问量:102

问:

我在 C 和 Fortran 中拥有广泛的现有代码库。我想编写一个 R 包,它使用 RCPP 包装一些高级 C 函数。我有兴趣通过 RCPP 调用的大多数 C 函数的本质是它们再次调用多个 C 头文件,其中许多链接到 Fortran 函数。

在将 Fortran 函数链接到我在 cpp 函数中包含的 C 标头时,我遇到了障碍。

下面是一个最小的可重复示例。它由三个文件组成,即 和 ,它们都位于通过 RStudio 创建的 RCPP 包项目的文件夹中。 定义了一个函数 rcpp_wrapper(),该函数旨在包装 中定义的 C 函数 complicated_c_fun()。此函数 complicated_c_fun() 调用 中定义的函数 FORTRANCODE()。当我尝试安装包(通过 RStudio Build -> Check)时,我收到以下错误消息:rcpp_script.cppc_header.hfortrancode.f90/srcrcpp_script.cppc_header.hfortrancode.f90

C:\RBuildTools\4.3\x86_64-w64-mingw32.static.posix\bin/ld.exe: rcpp_script.o:rcpp_script.cp:(.text+0x130): undefined reference to `FORTRANCODE_(double*)' C:\RBuildTools\4.3\x86_64-w64-mingw32.static.posix\bin/ld.exe: rcpp_script.o:rcpp_script.cp:(.text+0x160): undefined reference to `FORTRANCODE_(double*)' collect2.exe: error: ld returned 1 exit status

rcpp_script.cpp

#include <Rcpp.h>
#include "c_header.h"
using namespace Rcpp;

// [[Rcpp::export]]
double rcpp_wrapper(double p) {
  double z = complicated_c_fun(p);
  return z;
}

c_header.h

#ifndef C_HEADER_H
#define C_HEADER_H

double complicated_c_fun(double z) {
  double r;
  extern double FORTRANCODE_(double* z);
  r = FORTRANCODE_(&z);
  return (4*r);
}

#endif // C_HEADER_H

fortrancode.f90

DOUBLE PRECISION FUNCTION FORTRANCODE(P)
  
DOUBLE PRECISION P
  
IF ( P .LT. 1 ) THEN
  FORTRANCODE = 0
ELSE
  FORTRANCODE = 1
ENDIF
  
END FUNCTION FORTRANCODE

如何正确地将 Fortran 代码链接到 C 头文件?提前感谢您的帮助。

R C Fortran 链接器错误

评论

0赞 John Coleman 6/7/2023
“其中许多都链接到 Fortran 函数”——他们是如何做到的?了解现有 C 代码如何调用 Fortran 可能有助于您弄清楚如何从 R 中执行此操作。
0赞 Dirk is no longer here 6/7/2023
有使用 Fortran 的现有 CRAN 软件包。我本来会使用一个,但我认为这是一个已解决的问题(这与我认为无关 - 你只需要弄清楚如何告诉R编译和链接,这可能在R安装和管理和/或编写R扩展中。顺便说一句,我们把它写成 Rcpp.大写字母 R,小写字母 cpp。f90Rcpp
1赞 John Bollinger 6/7/2023
你到底为什么要在你的 C 头文件中放置一个函数定义?标头不应包含外部函数的定义,而应仅包含其声明。(但解决这个问题本身并不能解决你的问题。
1赞 John Bollinger 6/7/2023
@elmo,如果问题是关于从 C 函数调用 Fortran 函数,那么 C 函数本身是通过 C++ 从 R 调用的这一事实似乎是一条红鲱鱼。C 和 Fortran(以及 C++)是编译语言。其中一个调用另一个调用的所有细节都是在编译时设置的,而不是在调用时设置的,因此如何调用前端并不重要。
1赞 John Bollinger 6/7/2023
因此,我认为这可能是关于从 C 调用 Fortran 的许多问题中的一个或多个的欺骗,例如从 C 调用 FORTRAN 子例程混合 C、C++ 和 Fortran 中的代码等。然而,由于这个问题似乎引起了 R 社区的很多关注,但我不愿欺骗它。

答:

1赞 elmo 6/7/2023 #1

感谢 @DirkEddelbuettel 和 @JohnBollinger 的非常有用的评论,我明白我的问题与 Rcpp 无关,而是关于如何从 C++ 和 C 调用 Fortran。虽然我最初问题中的代码适用于使用的原始 C 编译器,但在使用 g++ 编译器时,需要包含 Fortran 函数,如下所示:

c_header.h:

#ifndef C_HEADER_H
#define C_HEADER_H

extern "C" {
  double fortrancode_(double* p);
}

double complicated_c_fun(double z) {
  double r;
  r = fortrancode_(&z);
  return (4*r);
}

#endif // C_HEADER_H