gpt4 book ai didi

c - 带有 Rcpp 的 .c 和 .cpp 文件的 R 包

转载 作者:行者123 更新时间:2023-12-03 23:36:26 26 4
gpt4 key购买 nike

我正在尝试使用 Rcpp 包作为依赖项构建一个包含 C(以 .c 文件的形式)和 C++ 代码(以 .cpp 文件的形式)的 R 包。

我有一些问题。

  • 首先,真的可以这样做吗?可以调用同一 R 包中的 C 脚本和 C++ 脚本吗?
  • 如果前一个是可能的,那么如何在 C 和 C++ 脚本中正确注册函数。

  • 为了帮助解决这个问题,我在我的 GitHub 页面 ( https://github.com/tpbilton/testrcpp) 上设置了一个小示例。我使用 Rcpp.package.skeleton("testrcpp") 来初始化包并添加了一些函数(来自本教程 https://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-introduction.pdf ),然后运行 ​​ Rcpp::compileAttributes() 。我安装了该软件包,并且 c++ 函数 convolve_cpp 工作正常,但 convolve_c 未注册,我不知道如何正确执行此操作,并且我尝试注册这两个函数的尝试无济于事。

    最佳答案

    First, is it actually possible to do this? Can one call C scripts and C++ scripts that are in the same R package?



    是的。众所周知,Rcpp 利用了 R 的 C API。 (参见 Section 1.6.4 Portable C and C++ codeWriting R Extensions

    If the previous is possible, how then does one properly register the functions in the C and C++ scripts.



    理想情况下,只从 C++ 脚本表面方面。否则,你会被困在写胶水里。

    我采取了这种方法。这篇文章继续详细介绍这些细微的变化。可以在异地找到一个工作示例:

    https://github.com/r-pkg-examples/rcpp-and-c

    简而言之,我们将为函数定义创建一个头文件并将其包含在 C 代码中。从那里,我们将创建第三个 C++ 文件,并使用 _Rcpp 将该函数导出到 R 中。

    convolve_in_c.h

    这里我们通过 #ifndef#define 使用包含保护来确保如果我们多次重用头文件,函数定义不会重复。
    #ifndef CONVOLVE_C_H
    #define CONVOLVE_C_H

    SEXP convolve_c(SEXP a, SEXP b);

    #endif /* CONVOLVE_C_H */

    convolve_in_c.c

    现在,让我们修改文件以允许我们的自定义 header 。
    #include <R.h>
    #include <Rinternals.h>

    // Incorporate our header
    #include "convolve_in_c.h"

    SEXP convolve_c(SEXP a, SEXP b) {
    int na, nb, nab;
    double *xa, *xb, *xab;
    SEXP ab;
    a = PROTECT(coerceVector(a, REALSXP));
    b = PROTECT(coerceVector(b, REALSXP));
    na = length(a); nb = length(b);
    nab = na + nb - 1;
    ab = PROTECT(allocVector(REALSXP, nab));
    xa = REAL(a); xb = REAL(b); xab = REAL(ab);
    for(int i = 0; i < nab; i++)
    xab[i] = 0.0;
    for(int i = 0; i < na; i++)
    for(int j = 0; j < nb; j++)
    xab[i + j] += xa[i] * xb[j];
    UNPROTECT(3);
    return ab;
    }

    convolve_from_c_to_rcpp.cpp

    最后,我们在 C++ 文件中使用 extern 合并 C 代码,以使 C++ 中的函数名称与 C 链接对齐。此外,我们将数据类型从 SEXP 操作为 NumericVector
    #include "Rcpp.h"

    // Define the method signature

    #ifdef __cplusplus
    extern "C" {
    #endif

    #include "convolve_in_c.h"

    #ifdef __cplusplus
    }
    #endif

    //' Call C function from Rcpp
    //'
    //' Uses the convolve_c function inside of a C++ routine by Rcpp.
    //'
    //' @param a,b A `numeric` vector.
    //'
    //' @return
    //' A `numeric` vector of length \eqn{N_a + N_b}.
    //'
    //' @examples
    //'
    //' convolve_from_c(1:5, 5:1)
    //'
    //' @export
    // [[Rcpp::export]]
    Rcpp::NumericVector convolve_from_c(const Rcpp::NumericVector& a,
    const Rcpp::NumericVector& b) {

    // Compute the result in _C_ from _C++_.
    SEXP ab = convolve_c(a, b);

    // Cast as an _Rcpp_ NumericVector
    Rcpp::NumericVector result( ab );

    // Alternatively:
    // Rcpp::NumericVector result( convolve_c(a, b) );

    // Return result
    return result;
    }

    关于c - 带有 Rcpp 的 .c 和 .cpp 文件的 R 包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54000015/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com