【问题标题】:Compiling C++ in Rcpp with external C library使用外部 C 库在 Rcpp 中编译 C++
【发布时间】:2016-06-14 18:53:33
【问题描述】:

我正在尝试使用Rcpp 代码构建一个使用外部库的 R 包。我之前曾向 SO 询问过如何在包 here 中使用外部 C 库。我遇到的问题是,只要我包含以下代码行

y = N_VNew_Serial(3);

我收到了错误

sundials_test.o:sundials_test.cpp:(.text+0x2ba): undefined reference to `N_VNew_Serial'
collect2: ld returned 1 exit status
Error in Rcpp::sourceCpp("src/sundials_test.cpp") : 
  Error occurred building shared library

我没有收到该行的错误

N_Vector y = NULL;

所以,我认为与图书馆的连接工作正常。我还确认N_VNewSerial() 的函数声明在nvector/nvector_serial.h 中,如果您需要查看整个包代码,可以使用here

特定Rcpp 文件的代码粘贴在下方

#include <Rcpp.h>

// #include <iostream.h>
#include <cvode/cvode.h>               /* prototypes for CVODE fcts., consts. */
#include <nvector/nvector_serial.h>    /* serial N_Vector types, fcts., macros */
#include <cvode/cvode_dense.h>         /* prototype for CVDense */
#include <sundials/sundials_dense.h>   /* definitions DlsMat DENSE_ELEM */
#include <sundials/sundials_types.h>   /* definition of type realtype */

using namespace Rcpp;

void InitialConditions (NumericVector x){

  N_Vector y = NULL;
  // y = N_VNew_Serial(3);
  //
  // NV_Ith_S(y,0) = 1;
  // NV_Ith_S(y,1) = 2;
  // NV_Ith_S(y,2) = 3;


}

我不确定为什么代码将 undefined reference 报告给一个函数,但没有报告给同一个头文件中的另一个函数,非常感谢任何有助于理解解决此错误的方法。

谢谢!

SN248

【问题讨论】:

    标签: c++ r rcpp r-package sundials


    【解决方案1】:

    这是一个链接错误,而不是编译错误。编译成功让您进入链接步骤。但是

    sundials_test.o:sundials_test.cpp:(.text+0x2ba): \
      undefined reference to `N_VNew_Serial'
    collect2: ld returned 1 exit status
    Error in Rcpp::sourceCpp("src/sundials_test.cpp") : 
      Error occurred building shared library
    

    非常清楚:R 无法构建共享库,因为您没有针对提供它的目标代码(我想来自日晷)链接

    【讨论】:

    • 非常感谢您@Dirk 的回复。我不知道如何链接目标代码。你能在这个过程中提供帮助吗?我的 Windows 机器上没有安装日晷。我正在尝试制作包,这样我就不必安装库,所以我已经在包本身中包含了所有源文件和头文件。谢谢!
    • 你是trying to declare them here。也许有些文件丢失了?或者也许依赖项 not 到达链接步骤?不知道,但这是你的问题。
    • 感谢您的回复,但要明确一点 - 这不是我包裹中的 Makevars 文件。我的包的Makevars 文件是-github.com/sn248/Rcppsbmod/blob/master/src/Makevars.win,我的印象是,为了包含一个外部库,我所要做的就是提供来自该库而不是共享库的头文件和源文件是在安装软件包时构建的,但我在这里可能非常错误。这里的任何见解都会非常有帮助。谢谢!
    • 在最后一个示例中,您使用两个日晷(子)库:-lsundials_cvode -lsundials_nvecserial。你需要对你的 R 包做同样的事情,这是 a) 独立于你是否使用 Rcpp 和 b) 在编写 R 扩展中明确记录。
    • 作为旁注,@SN248,您不应该使用Rcpp::sourceCpp() 来编译此代码。相反,您应该构建并重新加载包。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-19
    相关资源
    最近更新 更多