如何从R调用C函数?

时间:2015-01-19 14:24:06

标签: c r

如何使用R数据从R级使用C语言编写的某些函数。 例如。使用像:

这样的功能
double* addOneToVector(int n, const double* vector) {
    double* ans = malloc(sizeof(double)*n);
    for (int i = 0; i < n; ++i)
        ans[i] = vector[i] + 1
    return ans;
}

在上下文中:

x = 1:3
x = addOneToVector(x)
x # 2, 3, 4

3 个答案:

答案 0 :(得分:5)

我先搜索了stackoverflow,但我注意到这里没有答案。
一般的想法是(Linux的命令,但在其他操作系统下相同的想法):

  1. 创建只接受基本类型指针的函数,并通过副作用执行所有操作(返回void)。例如:

    void addOneToVector(int* n, double* vector) {
        for (int i = 0; i < *n; ++i)
            vector[i] += 1.0;
    }
    
  2. 将文件C源编译为动态库,可以使用R快捷键执行此操作:

    $ R CMD SHLIB lib.c
    
  3. 从R:

    加载动态库
    dyn.load("foo.so")
    
  4. 使用.C R函数调用C函数,IE:

    x = 1:3
    ret_val = .C("addOneToVector", n=length(x), vector=as.double(x))
    
  5. 返回列表,在调用函数后可以从中获取输入值,例如。

    ret_val$x # 2, 3, 4
    

    您现在可以将其包装起来,以便更轻松地使用它。

    这里有一个很好的页面描述整个过程,其中包含更多细节(也包括Fortran):

    http://users.stat.umn.edu/~geyer/rc/

答案 1 :(得分:2)

我只是使用Rcpp package以一种非常简单的方式做了同样的事情。它允许您直接在R中编写C ++函数。

library("Rcpp")
cppFunction("
NumericVector addOneToVector(NumericVector vector) {
  int n = vector.size();

  for (int i = 0; i < n; ++i)
    vector[i] = vector[i] + 1.0;

  return vector;
}")

http://adv-r.had.co.nz/Rcpp.html处找到更多详细信息。这些说明可以非常快速地完成C ++函数。

答案 2 :(得分:0)

首先,我要感谢@ m0nhawk和@Jan对这个问题的巨大贡献。

我在MacBook上尝试了两种方法:首先显示m0nhawk,这需要在C中创建一个函数(不使用main方法),然后使用R CMD SHLIB <prog.c>进行编译,然后使用.C命令从R调用该函数。

这是我写的一小段C代码(不是C语言的专业人士-只是一点一点地学习)

第1步:编写C程序

#include <stdio.h>
int func_test() {
    
    for(int i = 0; i < 5; i++) {
        printf("The value of i is: %d\n", i);
    }
    return 0;

}

第2步:使用编译程序

R CMD SHLIB func_test.c

这将产生一个func_test.so文件

步骤3:现在编写从R Studio内部调用此C函数的R代码

dyn.load("/users/my_home_dir/xxx/ccode/ac.so")
.C("func_test")

第4步:输出:

.C(“ func_test”)i的值是:0 i的值是:1 i的值是:2 i的值是:3 i的值是:4 list()

然后我尝试了Jan建议的直接方法-使用RCpp软件包

library("Rcpp")
cppFunction("
NumericVector addOneToVector(NumericVector vector) {
  int n = vector.size();

  for (int i = 0; i < n; ++i)
    vector[i] = vector[i] + 1.0;

  return vector;
}")

# Test code to test the function
addOneToVector(c(1,2,3))

这两种方法都非常有效。我现在可以开始用C或C ++编写函数并在R中使用它们

再次感谢您!