从R对象中提取long []

时间:2011-02-15 20:18:02

标签: r rcpp

我正在尝试为一些基于C的稀疏矩阵处理代码创建一个包装器(参见previous question)。为了调用workhorse C函数,我需要创建一个如下所示的结构:

struct smat {
  long rows;
  long cols;
  long vals;     /* Total non-zero entries. */
  long *pointr;  /* For each col (plus 1), index of first non-zero entry. */
  long *rowind;  /* For each nz entry, the row index. */
  double *value; /* For each nz entry, the value. */
};

这些与dgCMatrix稀疏矩阵中的槽很好地对应。理想情况下,我只是指向dgCMatrix中的内部数组(在验证C函数不会改变数据之后[我还没有完成])。

对于*value,看起来我可以根据需要使用REALSXP或其他内容来获取double[]。但是对于*pointr*rowind,我不确定获得适当数组的最佳方法。我是否需要遍历这些条目并将它们复制到新的数组中,然后进行投射?或者Rcpp可以在这里提供一些糖吗?这是我第一次真正使用Rcpp并且我还没精通它。

感谢。

编辑:我也遇到了一些我不理解的链接问题:

Error in dyn.load(libLFile) : 
  unable to load shared object '/var/folders/TL/TL+wXnanH5uhWm4RtUrrjE+++TM/-Tmp-//RtmpAA9upc/file2d4606aa.so':
  dlopen(/var/folders/TL/TL+wXnanH5uhWm4RtUrrjE+++TM/-Tmp-//RtmpAA9upc/file2d4606aa.so, 6): Symbol not found: __Z8svdLAS2AP4smatl
  Referenced from: /var/folders/TL/TL+wXnanH5uhWm4RtUrrjE+++TM/-Tmp-//RtmpAA9upc/file2d4606aa.so
  Expected in: flat namespace
 in /var/folders/TL/TL+wXnanH5uhWm4RtUrrjE+++TM/-Tmp-//RtmpAA9upc/file2d4606aa.so

我是否需要使用一些特殊的编译标志来创建我的库?

编辑2:看起来我的libargs参数无效,因此libsvd符号永远不会进入库中。我找不到使用cxxfunction()包含库的方法 - 这就是我尝试过的内容,但是额外的参数(从cfunction()那里一厢情愿地借来的)是默默无闻的:

fn <- cxxfunction(sig=c(nrow="integer", mi="long", mp="long", mx="numeric"), 
                  body=code,
                  includes="#include <svdlib.h>\n", 
                  cppargs="-I/Users/u0048513/Downloads/SVDLIBC", 
                  libargs="-L/Users/u0048513/Downloads/SVDLIBC -lsvd", 
                  plugin="Rcpp",
                  verbose=TRUE)

我觉得我整个过程都是错误的,因为没有任何工作。有人踢我正确的方向吗?

2 个答案:

答案 0 :(得分:1)

我决定在Rcpp-devel邮件列表上发布一个查询,并得到了一些很好的建议&amp;德克和道格的帮助:

http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2011-February/001851.html

对于这些东西,我仍然不是超级轻松,但到了那里。 =)

答案 1 :(得分:0)

去年我为[R] -Smalltalk接口做了类似的事情,并且通过使用字节数组来传递所有数据更加通用:

在C中我有:

DLLIMPORT void getLengthOfNextMessage(byte* a);
DLLIMPORT void getNextMessage(byte* a);

在R:

getLengthOfNextMessage <- function() {
    tmp1  <- as.raw(rep(0,4))
    tmp2<-.C("getLengthOfNextMessage", tmp1)
    return(bvToInt(tmp2))
}

receiveMessage <- function() {
    #if(getNumberOfMessages()==0) {
    #   print("error: no messages")
    #   return();
    #}
    tmp1<-as.raw(rep(0, getLengthOfNextMessage()+getSizeOfMessages()))
    tmp2<-.C("getNextMessage", tmp1)
    msg<-as.raw(tmp2[[1]])
        print(":::confirm received")
        print(bvToInt(msg[13:16]))
    # confirmReceived(bvToInt(msg[13:16]))
    return(msg)
}

我已经注释掉了函数getNumberOfMessages()和confirmReceived()的使用,这些函数特定于我必须解决的问题(多次来回通信)。本质上,代码使用参数字节数组来传输信息,首先是4字节长的信息,然后是实际数据。这似乎不太优雅(甚至对我而言)比使用结构,但我发现它更通用,我可以挂钩到任何dll,传输任何数据类型。