5

xts-0.9-1 包提供的 xts_API for C 不能直接在 C++ 中使用。

例如,如果一个人写

#include <Rcpp.h>
extern "C" {
#include <xts.h>
}

using namespace Rcpp;

RcppExport SEXP get_xts_index(SEXP x, SEXP value) {
  BEGIN_RCPP

  return SET_xtsIndexClass(x, value);

  END_RCPP
}

会出现以下编译时错误:

  • error: expected identifier before ‘)’ token
  • error: ‘install’ was not declared in this scope
  • error: ‘getAttrib’ was not declared in this scope
  • error: ‘setAttrib’ was not declared in this scope
  • error: ‘xts_IndexvalueSymbol’ was not declared in this scope

如何为 C 调用 xts_API?

4

2 回答 2

5

你有什么版本的xts?以下对我有用:

library(xts)
library(inline)

inc <- '
extern "C" {
#define class xts_class
#include <xts.h>
#undef class
}


inline SEXP install(const char* x) {
  return Rf_install(x);
}

inline SEXP getAttrib(SEXP a, SEXP b) {
  return Rf_getAttrib(a, b);
}


inline SEXP setAttrib(SEXP a, SEXP b, SEXP c) {
  return Rf_setAttrib(a, b, c);
}

#include <Rcpp.h>
'

src <- '
   return GET_xtsIndexClass(x);
'

Sys.setenv("PKG_CXXFLAGS"="-I/usr/local/lib/R/site-library/xts/include")
xtsfun <- cxxfunction(signature(x="ANY"), body=src, inc=inc, plugin="Rcpp")

我可以运行:

R> xtsfun <- cxxfunction(signature(x="ANY"), body=src, inc=inc, plugin="Rcpp")
R> foo <- xts(1:5, order.by=Sys.time()+0:4)
R> xtsfun(foo)
[1] "POSIXct" "POSIXt" 
R> 

包含标志设置需要通用化,但如果您来到 rcpp-devel 列表,我们可以进行这项工作。

编辑:我开始尝试一个附加包,它与 xts 的(目前比较有限的)API 接口;请参阅 R-Forge 上的 Rcpp SVN 存储库。我还向 Rcpp Gallery 添加了一个新答案,该答案展示了如何从 C++ 代码访问 xts 组件。有更好的方法来获取属性(使用 Rcpp API)然后在这里使用(基于 R 的 C API)。

编辑 2:现在有一个新的包RcppXts可以帮助解决这个问题。

于 2013-01-11T12:32:52.737 回答
1

以下指南适用于 R 包开发。

关键是添加必要的内联函数和宏以使 xts_API 与 C++ 兼容。

extern "C" {
#define class xts_class
#include <xts.h>
#undef class
}


inline SEXP install(const char* x) {
  return Rf_install(x);
}

inline SEXP getAttrib(SEXP a, SEXP b) {
  return Rf_getAttrib(a, b);
}


inline SEXP setAttrib(SEXP a, SEXP b, SEXP c) {
  return Rf_setAttrib(a, b, c);
}

#include <Rcpp.h>

RcppExport SEXP get_xts_index(SEXP x, SEXP value) {
  BEGIN_RCPP

  return GET_xtsIndexClass(x);

  END_RCPP
}

上面的代码应该适用于几乎所有的 xts_API,除了SET_xtsIndexClass.

编译器仍会报告error: ‘xts_IndexvalueSymbol’ was not declared in this scope.

这是我的解决方案,但我不知道它是否正确。

开放<xts package root>/include/xts.h和改变

#define  SET_xtsIndexClass(x,value)     setAttrib(x, xts_IndexvalueSymbol, value)

#define  SET_xtsIndexClass(x,value)     setAttrib(x, xts_IndexClassSymbol, value)

我想这是一个错字。

于 2013-01-11T08:07:59.580 回答