如何处理R和C+中调用约定的不匹配+;使用Rcpp? 我正在开发一个带有C++功能的R包。我使用Rcpp。在编写和测试时,一切都很好。但是,当我完成并在循环中运行它时,偶尔会收到以下警告和错误:
警告:'.Call',78和77中的堆栈不平衡 警告:“{”、75和74中的堆栈不平衡 警告:'.Call',78和79中的堆栈不平衡 警告:{',75然后76中的堆栈不平衡 警告:'.Call',78和77中的堆栈不平衡 警告:“{”、75和74中的堆栈不平衡 所以我在谷歌上搜索了堆栈不平衡,发现: 本文指出堆栈不平衡通常是由不同语言之间调用约定的差异(不匹配)造成的。据我所知,调用约定是关于调用方函数删除局部变量还是被调用方函数删除的协议 我发现:如何处理R和C+中调用约定的不匹配+;使用Rcpp? 我正在开发一个带有C++功能的R包。我使用Rcpp。在编写和测试时,一切都很好。但是,当我完成并在循环中运行它时,偶尔会收到以下警告和错误: ,c++,r,rcpp,calling-convention,C++,R,Rcpp,Calling Convention,警告:'.Call',78和77中的堆栈不平衡 警告:“{”、75和74中的堆栈不平衡 警告:'.Call',78和79中的堆栈不平衡 警告:{',75然后76中的堆栈不平衡 警告:'.Call',78和77中的堆栈不平衡 警告:“{”、75和74中的堆栈不平衡 所以我在谷歌上搜索了堆栈不平衡,发现: 本文指出堆栈不平衡通常是由不同语言之间调用约定的差异(不匹配)造成的。据我所知,调用约定是关于调用方函数删除局部变量还是被调用方函数删除的协议 我发现: 它表示R使用代码> CDECL < /
它表示R使用代码> CDECL < /C> > C++使用“代码> STDCALL< /COD> < < /P>” “如果您的函数使用
stdcall
而不是cdecl
,则返回时可能会出现崩溃,因为参数在消失后将从堆栈中删除。”
如果我在声明中有任何错误,请告诉我
这是我的R代码调用的C++函数:
//[[Rcpp::export]]
int compute(SEXP p_in, Rcpp::NumericVector a) {
Rcpp::XPtr<emcdf> p(p_in);
p->cdf(a);
return p->getResult();
}
//p_in is an external pointer(pointer to an emcdf object in C++)
/[[Rcpp::export]]
int计算(SEXP_in,Rcpp::NumericVector a){
Rcpp::xptrp(p_in);
p->cdf(a);
返回p->getResult();
}
//p_in是一个外部指针(C++中指向emcdf对象的指针)
所以,我的问题是,我如何解决这个问题
我感谢你的帮助
更多详情和代码2.14.2017
谢谢你们的回答。下面是更多的代码:
//declaration of class "emcdf"
class emcdf{
public:
explicit emcdf(Rcpp::NumericMatrix& x, int n);
~emcdf();
void cdf(Rcpp::NumericVector& a);
int getResult();
private:
int num;
int k;
std::thread* t;
std::vector<Rcpp::NumericMatrix*> data;
int size;
int* result;
void (*ptr) (Rcpp::NumericMatrix*, Rcpp::NumericVector, int*);
void find_func();
};
//definition of class "emcdf"
emcdf::emcdf(Rcpp::NumericMatrix& x, int n){
//initialize members
t = new std::thread[n];
num = n;
k = x.ncol();
size = x.nrow()/num;
result = new int[num];
find_func();
int i = 0;
for(; i<num - 1; ++i)
data.push_back(copy(x, i*size, size));
data.push_back(copy(x, i*size, x.nrow() - i*size));
}
emcdf::~emcdf(){
delete[] t;
for(int i=0; i<num; ++i)
delete data[i];
delete[] result;
}
void emcdf::cdf(Rcpp::NumericVector& a){
for(int i=0; i<num; ++i){
t[i] = std::thread(*ptr, data[i], a, result + i);
}
for(int i=0; i<num; ++i)
t[i].join();
}
int emcdf::getResult(){
int sum = 0;
for(int i=0; i<num; ++i)
sum += result[i];
return sum;
}
//other functions
Rcpp::NumericMatrix* copy(Rcpp::NumericMatrix& x, int row, int nrow){
NumericMatrix* out = new NumericMatrix(nrow, x.ncol());
int firstRow = 0;
while(firstRow < nrow){
for(int j=0; j<x.ncol(); ++j){
out->at(firstRow,j) = x.at(firstRow + row,j);
}
++firstRow;
}
return out;
}
//makes "emcdf" pointer
//[[Rcpp::export]]
RcppExport SEXP build(SEXP x_in, int num){
Rcpp::NumericMatrix x(x_in);
emcdf* em = new emcdf(x, num);
Rcpp::XPtr<emcdf> p(em, true);
return p;
}
//take pointer of "emcdf" from build() and compute cdf results
//[[Rcpp::export]]
int compute(SEXP& p_in, Rcpp::NumericVector& a){
Rcpp::XPtr<emcdf> p(p_in);
p->cdf(a);
return p->getResult();
}
//类“emcdf”的声明
类emcdf{
公众:
显式emcdf(Rcpp::NumericMatrix&x,int n);
~emcdf();
无效cdf(Rcpp::NumericVector&a);
int getResult();
私人:
int-num;
int k;
std::thread*t;
std::矢量数据;
整数大小;
int*结果;
void(*ptr)(Rcpp::NumericMatrix*,Rcpp::NumericVector,int*);
void find_func();
};
//“emcdf”类的定义
emcdf::emcdf(Rcpp::numerimatrix&x,int n){
//初始化成员
t=新标准::螺纹[n];
num=n;
k=x.ncol();
大小=x.nrow()/num;
结果=新整数[num];
查找函数();
int i=0;
对于(;i我认为你不幸地在最初的诊断上走错了方向
当R报告堆栈不平衡时,意味着内部保护堆栈(用于保护堆栈上的R对象与垃圾收集器)不平衡,表明某个C/C++例程中某个东西出现了同步。这与调用约定无关。
Rcpp通常在保护堆栈之外管理其对象的保护;它显式地使用
R\u PreserveObject()
和R\u ReleaseObject()
API,这些API不是基于堆栈的
如果没有一个可重复的示例,很难说得更多,但最可能的原因是您在尚未显示的单独代码中对PROTECT()
/UNPROTECT()
的调用不匹配。我认为您在最初诊断时不幸走错了方向
当R报告堆栈不平衡时,意味着内部保护堆栈(用于保护堆栈上的R对象与垃圾收集器)不平衡,表明某个C/C++例程中某个东西出现了同步。这与调用约定无关。
Rcpp通常在保护堆栈之外管理其对象的保护;它显式地使用
R\u PreserveObject()
和R\u ReleaseObject()
API,这些API不是基于堆栈的
如果没有可复制的示例,很难说更多,但最可能的原因是对PROTECT()
/UNPROTECT()的调用不匹配
在您尚未显示的单独代码中。这是您代码中的一个基本错误。如果您使用Rcpp,您永远不需要保护
和取消保护
。目前的问题是,没有人可以帮助您,因为这里没有可复制的内容。德克,您是对的,我在谷歌上搜索过,这个问题很难解决,因为很难重新编程你能告诉我什么是“基本错误”吗您认为它可能是或位于?谢谢。您需要提供更多详细信息,即p_in
最初是如何创建的?emcdf
类是如何定义的?此外,应该没有理由将p_in
作为SEXP
传递,并构造一个本地Rcpp::XPtr
,您可以只传递p_in
作为一个Rcpp::XPtr
并直接对其进行操作。我尝试将Rcpp::XPtr作为参数传递,结果在构建包时出现错误:“emcdf未在此范围内声明”。然后我遵循了一个示例(很抱歉,我现在找不到它)并且得到了我当前的代码。我从来没有在我的代码中使用过保护和取消保护。这是你代码中的一个基本错误。如果你使用Rcpp,你永远不需要保护和取消保护。现在的问题是,没有人能帮你,因为这里没有可复制的东西。德克,你是对的,我在谷歌上搜索过,这个问题很难解决很难复制。你能告诉我什么是“基本错误”吗您认为它可能是或位于?谢谢。您需要提供更多详细信息,即p_in
最初是如何创建的?emcdf
类是如何定义的?此外,应该没有理由将p_in
作为SEXP
传递,并构造一个本地Rcpp::XPtr
,您可以只传递p_in
作为一个Rcpp::XPtr
并直接对其进行操作。我尝试将Rcpp::XPtr作为参数传递,结果在构建包时出现错误:“emcdf未在此范围内声明”。然后我按照一个示例(抱歉,我现在找不到它)获得了当前代码。我在代码中从未使用过PROTECT和UNPROTECT。谢谢。我从未使用过PRO