首页 > 解决方案 > 在 C++ 项目中设置 R (C api)

问题描述

我想在我自己的 cpp 项目中使用 R 包(AlgDesign - https://github.com/jvbraun/AlgDesign/tree/master/src )的 cpp 功能。

我常用的 IDE 是 Visual Studio 2015。我发现这篇相关的帖子Building R packages (C API) with Visual Studio(以及How do I compile a dll with R and RCPP?)所以我在 Windows 8.1 上安装了 MinGW 和 CodeBlocks IDE 和重试。我将“Rdir/include”路径添加到 CodeBlocks 中的“项目构建选项->搜索目录->编译器”。

但我仍然得到“未定义的引用_GetRNGstate”,它相当于MSVC“未解析的外部符号_GetRNGstate”。所以我猜这个问题是一个缺失的库,就像已经提到的原始提问者一样。但我也不知道是哪一个。我的 R-install 目录中没有 .lib 文件。

此外,我不打算使用 Rcpp 或构建自己的 R 包,我只是想在我自己的 cpp-project 中访问 SEXP FederovOpt(..args) 函数

编辑:假设我想将 AlgDesign src 文件函数逐个函数传输到一个空项目中。在某些时候我会达到这个:

#include "wheeler.h"

#include <string.h>
#include <stdlib.h>
#include <Rinternals.h>
#include <Rdefines.h>
#include <R.h>
#include <Rmath.h>
#include <R_ext/RS.h>
#include <R_ext/Utils.h>

/* Permute **********************************************************
|   Randomly pemutes the n integers in a[] using the Fike
|   algorithm.  See Fike, "A permutation generation method"  The Computer
|   Journal, 18-1, Feb 75, 21-22.
*/

void Permute(
    int     *a,
    int     n
)
{
    int         i,
        j,
        temp;

    GetRNGstate();
    for (i = 1; i < n; i++) {
        j = (int)((double)(1 + i)*unif_rand());
        temp = a[j];
        a[j] = a[i];
        a[i] = temp;
    }
    PutRNGstate();
}

int main(){

return 0;

}

我将 在 RC API 的 Random.h 中定义void GetRNGstate(void)的 RC API 的 Random.h 中定义的 3 个未解析的外部变量在 RC API void PutRNGstate(void)的 Random.h 中 double unif_rand(void)定义

最后,我找到了这篇文章:https ://www.codeproject.com/Questions/1192515/I-want-to-run-R-script-from-Cplusplus-code

所以当然,我正在寻找一个 .lib 文件。但是这个文件在 Windows 中不存在,我必须自己创建 .lib 文件。但我不知道怎么做。我找到了这个,但它很旧,目录完全不同:https ://uploads.cosx.org/2009/12/Integrate-R-into-C.pdf

请你帮助我好吗?一个简单的“轻松使用makefile”或单个cmd命令对我没有帮助,我无法理解。我以前从未使用过makefile,也从未构建过.lib。

标签: c++r

解决方案


我看到两种可能的方法:

  1. 将 R 解释器嵌入到您的应用程序中,例如使用Rinside包。然后你可以调用环绕FederovOpt.
  2. FederovOpt函数包含了一些执行实际工作的普通 C 函数。它的主要任务是将这些 C 函数与 R 接口。如果您不使用 R,否则您也可以提取这些 C 函数并直接使用它们。

使用哪种解决方案?如果您需要其他 R 功能,1. 可能会更容易。查看 Rinside 附带的示例。您可能必须坚持使用 mingw,最好来自 Rtools。如果这是您需要的唯一 R 功能,那么 2. 可能是要走的路。如果你让代码独立于 R,你可以使用 VS。有些例子做了类似的事情,例如https://github.com/zhanxw/libMvtnorm。在这两种情况下,您都必须遵守 GPL。

为了使选项二更明确,我做了一个简单的测试:

  1. 下载FederovOpt.cwheeler.h.
  2. 删除所有#include特定于 R 的标头。
  3. 为and加上#include <math.h>and 。#defineTRUEFALSE
  4. 删除 R 特定功能ProgAllocProgDealloc以及FederovOpt
  5. 删除 R 特定的函数调用R_CheckUserInterrupt(),GetRNGstate()PutRNGstate().
  6. 替换unif_rand()rand() / (RAND_MAX + 1.0)

生成的文件可以在gcc没有错误或警告的情况下编译。当添加一个main(). 在那里,您将分配内存、调用FederovOptimize并再次释放内存。

顺便说一句,RNG 当然比 R 的 RNG 差得多,但可能足以完成这项任务。使用 C++11,您当然有更好的可能性。


推荐阅读