R 包:在 Rcpp 中调用 C 函数
R Package: Call C Function Within Rcpp
我正在编写一个包含 C 和 Rcpp 的 R 包。目标是从 R 和 Rcpp 中调用 C 函数,最终在 Rcpp 中执行大部分分析,并且只返回 R 执行最少的任务。我的包编译并从 R 调用我的函数工作正常。
#generate some matrix. Numeric is fine too. Must have column names, no row names
myMat <- matrix(data = 1:100, nrow = 10, ncol = 10,
dimnames = list(NULL, LETTERS[1:10]))
#This works. Put in full path, no expansion. It returns null to the console.
MinimalExample::WriteMat(mat = myMat, file = "Full_Path_Please/IWork.csv",
sep = "," ,eol = "\n", dec = ".", buffMB = 8L)
但是,在 Rcpp 中尝试同样的事情会产生 SIGSEV 错误。我认为问题在于我如何将参数传递给函数,但我想不出正确的方法。
#include <Rcpp.h>
using namespace Rcpp;
extern "C"{
#include "fwrite.h"
}
//' @export
// [[Rcpp::export]]
void WriteMatCpp(String& fileName, NumericMatrix& testMat){
Rcpp::Rcout<<"I did start!"<<std::endl;
String patchName = fileName;
int whichRow = 1;
std::string newString = std::string(3 - toString(whichRow).length(), '0')
+ toString(whichRow);
patchName.replace_last(".csv", newString+".csv");
//Set objects to pass to print function
String comma = ",";
String eol = "\n";
String dot = ".";
int buffMem = 8;
//This is where I crash, giving a SIGSEV error
fwriteMain(testMat, (SEXP)&patchName, (SEXP)&comma, (SEXP)&eol,
(SEXP)&dot, (SEXP)&buffMem);
}
这是 link 到 GitHub 存储库的软件包。 https://github.com/GilChrist19/MinimalExample
你从C++到C的调用是错误的。你不能只在任意数据结构前面写 (SEXP)&
,然后希望它变成 SEXP
。
修复
使用这样的一行将您在 C++ 中的内容转换为您的 C 函数期望的 SEXP
在每个参数上使用 Rcpp::wrap()
:
//This is where I crash, giving a SIGSEV error
fwriteMain(wrap(testMat), wrap(patchName), wrap(comma),
wrap(eol), wrap(dot), wrap(buffMem));
演示
edd@brad:/tmp/MinimalExample/MinEx(master)$ Rscript RunMe.R
I did start!
edd@brad:/tmp/MinimalExample/MinEx(master)$ cat /tmp/IDoNotWork.csv
A,B,C,D,E,F,G,H,I,J
1,11,21,31,41,51,61,71,81,91
2,12,22,32,42,52,62,72,82,92
3,13,23,33,43,53,63,73,83,93
4,14,24,34,44,54,64,74,84,94
5,15,25,35,45,55,65,75,85,95
6,16,26,36,46,56,66,76,86,96
7,17,27,37,47,57,67,77,87,97
8,18,28,38,48,58,68,78,88,98
9,19,29,39,49,59,69,79,89,99
10,20,30,40,50,60,70,80,90,100
edd@brad:/tmp/MinimalExample/MinEx(master)$
有关完整示例,请参阅 https://github.com/GilChrist19/MinimalExample/tree/master/MinEx。
我正在编写一个包含 C 和 Rcpp 的 R 包。目标是从 R 和 Rcpp 中调用 C 函数,最终在 Rcpp 中执行大部分分析,并且只返回 R 执行最少的任务。我的包编译并从 R 调用我的函数工作正常。
#generate some matrix. Numeric is fine too. Must have column names, no row names
myMat <- matrix(data = 1:100, nrow = 10, ncol = 10,
dimnames = list(NULL, LETTERS[1:10]))
#This works. Put in full path, no expansion. It returns null to the console.
MinimalExample::WriteMat(mat = myMat, file = "Full_Path_Please/IWork.csv",
sep = "," ,eol = "\n", dec = ".", buffMB = 8L)
但是,在 Rcpp 中尝试同样的事情会产生 SIGSEV 错误。我认为问题在于我如何将参数传递给函数,但我想不出正确的方法。
#include <Rcpp.h>
using namespace Rcpp;
extern "C"{
#include "fwrite.h"
}
//' @export
// [[Rcpp::export]]
void WriteMatCpp(String& fileName, NumericMatrix& testMat){
Rcpp::Rcout<<"I did start!"<<std::endl;
String patchName = fileName;
int whichRow = 1;
std::string newString = std::string(3 - toString(whichRow).length(), '0')
+ toString(whichRow);
patchName.replace_last(".csv", newString+".csv");
//Set objects to pass to print function
String comma = ",";
String eol = "\n";
String dot = ".";
int buffMem = 8;
//This is where I crash, giving a SIGSEV error
fwriteMain(testMat, (SEXP)&patchName, (SEXP)&comma, (SEXP)&eol,
(SEXP)&dot, (SEXP)&buffMem);
}
这是 link 到 GitHub 存储库的软件包。 https://github.com/GilChrist19/MinimalExample
你从C++到C的调用是错误的。你不能只在任意数据结构前面写 (SEXP)&
,然后希望它变成 SEXP
。
修复
使用这样的一行将您在 C++ 中的内容转换为您的 C 函数期望的 SEXP
在每个参数上使用 Rcpp::wrap()
:
//This is where I crash, giving a SIGSEV error
fwriteMain(wrap(testMat), wrap(patchName), wrap(comma),
wrap(eol), wrap(dot), wrap(buffMem));
演示
edd@brad:/tmp/MinimalExample/MinEx(master)$ Rscript RunMe.R
I did start!
edd@brad:/tmp/MinimalExample/MinEx(master)$ cat /tmp/IDoNotWork.csv
A,B,C,D,E,F,G,H,I,J
1,11,21,31,41,51,61,71,81,91
2,12,22,32,42,52,62,72,82,92
3,13,23,33,43,53,63,73,83,93
4,14,24,34,44,54,64,74,84,94
5,15,25,35,45,55,65,75,85,95
6,16,26,36,46,56,66,76,86,96
7,17,27,37,47,57,67,77,87,97
8,18,28,38,48,58,68,78,88,98
9,19,29,39,49,59,69,79,89,99
10,20,30,40,50,60,70,80,90,100
edd@brad:/tmp/MinimalExample/MinEx(master)$
有关完整示例,请参阅 https://github.com/GilChrist19/MinimalExample/tree/master/MinEx。