R与C的接口:从R调用C的共享库

2009-03-11 05:10

R与C的接口:从R调用C的共享库

by wentrue

at 2009-03-10 21:10:57

original http://www.wentrue.net/blog/?p=72

R具有强大的可扩展性,提供包括C/C++、Fortran等等语言的接口,其计算能力也通过这些强悍的底层语言而得到极大的拓展。这里介绍怎样写R代码调用由C生成的共享库。 最简单的例子: 一、建立一个C文件,名为userC1.c void useC(int i, int j) { j[0] = i[0]+10; } 二、编译C程序 R CMD SHLIB useC1.c 或 gcc -c userC1.c R CMD SHLIB userC1.o 三、在R中进行如下调用

> dyn.load("useC1.so")   #注:动态载入共享库 > out=.C("useC", a=as.integer(c(1,2,3)), b=as.integer(c(0,2,3)))   #注:第一个参数为要调用的函数名 > a [1]  1  2  3 > out$b [1] 11  2  3

需要注意的地方: 1、编写的C函数不能有显式返回值,即函数返回要声明为void; 2、要得到函数的计算结果,只能通过传址实参的方式,在C参数中传递某个指针作为计算结果; 3、函数返回一个list,其中每个元素对应同名字的参数。 4、R中传参时参数的类型为vector,解释到C处对应就是指针。所以C函数参数必须声明为指针,这点要切记,否则会带来意想不到的结果。 5、传递数值向量时,默认为double型,可通过as.integer函数转换为integer型。 6、例子中R调用的工作原理:参数被拷贝一份,传递到C函数,计算,各参数拷贝到out这个list,返回。所以原工作区的变量不会被改变。 四、注意数据类型的显式声明,用as.函数来显式注明要传递的参数类型,以免到C处发生不可预料的错误。 / useC2.c                                         / void useC(int i, double d, char **c, int l) { i[0] = 11; d[0] = 2.333; c[1] = "g"; l[0] = 0; } 在命令行中运行如下命令: R CMD SHLIB useC2.c 生成动态库useC2.so 可以这样来编译连接多个源文件 R CMD SHLIB file1.c [...]