前言:
- 第一次接触R中调用C,网上搜索这个问题,有关的记录太少了,并且遇到了不少问题,在此记录R中调用C函数的步骤以及遇到的一些问题及解决方案。
- 这也是我的第一篇博客,有何不妥的望指出。
参考链接:
https://www.cnblogs.com/lmj-sky/p/10308988.html
http://r.dataguru.cn/article-3064-1.html
http://mazamascience.com/WorkingWithData/?p=1067
https://cran.r-project.org/doc/manuals/R-exts.html#System-and-foreign-language-interfaces
Why? 为什么要R、C混编?
R是一个优秀的统计计算语言,但是因为它是解释型语言, 所以在对数组元素的迭代运算方面会很慢。 在R用C语言程序可以既保留R的易用性又可以在必要时提高速度。——忘了从哪看到的了
通俗的讲就是提高运行速度
主要流程:
1:安装 Rtools、mingw并配置环境
2:在RStudio中运行下面两行代码生成dll文件
setwd("H:/test/Rcpp_test") #设置c文件的路径
system("R CMD SHLIB massdistnew.c") #编译c文件
3:载入dll文件并调用C文件的函数:
dyn.load('H:/test/Rcpp_test/massdistnew.dll')
y = .C("massdisttest", x = as.double(xtrunc), xmass = as.double(tau[trunc]/sum(tau[trunc])), nx = nx, xlo = as.double(lo), xhi = as.double(up),y = double(2 * n), ny = as.integer(n))$y
具体步骤一:Rtools、mingw的安装
What?
Rtools提供了一个适用于R的Windows平台工具链,它主要包括GNU make,GNU gcc和UNIX-ish平台上常用的其他实用程序。
MinGW,是Minimalist GNUfor Windows的缩写。它是一个可*使用和*发布的Windows特定头文件和使用GNU工具集导入库的集合,允许你在GNU/Linux和Windows平台生成本地的Windows程序而不需要第三方C运行时(C Runtime)库。-来自百度百科
目的:
用于编译c文件
安装(在RStudio中安装):
我这里用了简单的方式同时安装Rtools和mingw(对于先前未安装过的),当然也可以分步,先安装Rtools再安装mingw。
RStudio —》File —》New File –》 C++ File,这时会弹出”RTools没有安装“的提示,点击“是”,就自动下载RTools
遇到问题:下载完成后报错安装文件已损坏
原因:由于杀毒软件的问题,下载的安装文件被损坏
解决方案:关闭杀毒软件后,重新下载,下载完成后会自动安装
自解压安装完成,我们就会在目录C:\RBuildTools\3.X看到version.txt,这里就是RTools和mingw的安装路径
测试:
RStudio中输入:
system('g++ -v')
system('where make')
输出如下则安装成功
这里可能碰到2个问题都是与RTools和mingw的环境配置相关:
1、system('g++ -v') 输出-ERROR 127
2、system('where make') 输出-用提供的模式无法找到文件
解决方案:将Rtools 安装文件中的bin 以及mingw的 bin 文件添加到环境变量path中,注:mingw有32位和64位之分
具体步骤二:在R语言中运行下面两行代码生成dll文件
setwd("H:/test/Rcpp_test")
system("R CMD SHLIB regrf.c")
报错:make error 127:
原因:R中默认的Rtools的mingw路径与刚安装的路径不同
解决方案:编辑D:/Install/R/R-3.5.2/etc/x64的makeconf文件
BINPREF ?= c:/Rtools/mingw_64/bin/改为BINPREF ?= C:/RBuildTools/3.5/mingw_64/bin/
报错:collect2.exe: error: ld returned 1 exit status
原因: 链接失败问题,链接程序的主要工作就是将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够诶操作系统装入执行的统一整体。
解决方案:
相关的.c源文件(同个项目的)全部同时编译,并且谁在最前生成谁的dll文件(windows的可执行文件),如为了生成这三个文件的dll文件,执行三次
system('R CMD SHLIB regrf.c regTree.c rfutils.c') #生成regrf.dll
system('R CMD SHLIB regTree.c regrf.c rfutils.c') #生成regTree.dll
system('R CMD SHLIB rfutils.c regTree.c regrf.c') #生成rfutils.dll
注:发现RStudio右侧的文件目录中不能显示.o和.dll文件
具体步骤三:载入dll文件并调用C文件的函数
dyn.load('H:/test/Rcpp_test/massdistnew.dll')
y = .C("massdisttest", x = as.double(xtrunc), xmass = as.double(tau[trunc]/sum(tau[trunc])), nx = nx, xlo = as.double(lo), xhi = as.double(up),y = double(2 * n), ny = as.integer(n))$y
下划线部分为C文件中massdisttest函数的形参
这里除了用.C函数还可以用其它的如.call http://blog.sina.com.cn/s/blog_5ffd41cf01012gbq.html
结束