使用Rcpp,我在C++中定义了一个矩阵M。使用M.nrow()
,我们应该能够检索行数。但是,当我尝试将行数作为IntegerVector
返回时,答案是不正确的:
set.seed(1100)
M = matrix(sample(18), nrow = 6)
Rcpp::cppFunction('IntegerVector tccp5(IntegerMatrix M) { int x = M.nrow(); return x;}')
tccp5(M)
# [1] 0 0 0 0 0 0
正确答案应该是行数,例如
# [1] 6
你能解释一下发生了什么吗?
虽然@gfgm的答案是正确的,但我想扩展为什么声明为int
而不是IntegerVector
会导致正确的结构......
特别是,每次返回R都使用wrap()
无缝转换为SEXP
或指向结构的S表达式。通过提供IntegerVector
并返回int
,wrap()
必须实例化一个新的长度IntegerVector
x
因为没有int
底层的SEXP
。另一方面,当定义的返回类型int
时,Rcpp的wrap()
功能能够正确地将int
强制为IntegerVector
。
为了强调发生的基础"无缝"转换,让我们将参数verbose = TRUE
添加到cppFunction()
以查看C++代码是如何进行的:编译、链接和导入到R中。(注意:我已将输出截断到编译中。
如果我们考虑:
Rcpp::cppFunction('IntegerVector tccp5(IntegerMatrix M) { int x = M.nrow(); return x;}',
verbose = TRUE)
我们得到:
Generated code for function definition:
--------------------------------------------------------
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
IntegerVector tccp5(IntegerMatrix M) { int x = M.nrow(); return x;}
Generated extern "C" functions
--------------------------------------------------------
#include <Rcpp.h>
// tccp5
IntegerVector tccp5(IntegerMatrix M);
RcppExport SEXP sourceCpp_7_tccp5(SEXP MSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< IntegerMatrix >::type M(MSEXP);
rcpp_result_gen = Rcpp::wrap(tccp5(M));
return rcpp_result_gen;
END_RCPP
}
与以下相比:
Rcpp::cppFunction('int tccp5(IntegerMatrix M) { int x = M.nrow(); return x;}',
verbose = TRUE)
这给了:
Generated code for function definition:
--------------------------------------------------------
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
int tccp5(IntegerMatrix M) { int x = M.nrow(); return x;}
Generated extern "C" functions
--------------------------------------------------------
#include <Rcpp.h>
// tccp5
int tccp5(IntegerMatrix M);
RcppExport SEXP sourceCpp_9_tccp5(SEXP MSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< IntegerMatrix >::type M(MSEXP);
rcpp_result_gen = Rcpp::wrap(tccp5(M));
return rcpp_result_gen;
END_RCPP
}
异常输出是由于函数的类型声明而出现的。
library(Rcpp)
M <- matrix(sample(1:18), nrow=6)
cppFunction('int tccp6(IntegerMatrix M) { int x = M.nrow(); return x;}')
tccp6(M)
#> [1] 6
创建于 2018-03-22 由 reprex 包 (v0.2.0).