【问题标题】:Extract long[] from R object从 R 对象中提取 long[]
【发布时间】:2011-03-01 03:17:58
【问题描述】:

我正在尝试为一些基于 C 的稀疏矩阵处理代码制作一个包装器(请参阅previous question)。为了调用主力 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)

我觉得整个过程都错了,因为没有任何效果。有人把我踢到正确的方向吗?

【问题讨论】:

    标签: r rcpp


    【解决方案1】:

    我决定也在 Rcpp-devel 邮件列表上发布一个查询,并从 Dirk 和 Doug 那里得到了一些很好的建议和帮助:

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

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

    【讨论】:

      【解决方案2】:

      我去年为 [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,传输任何数据类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-19
        • 2020-09-06
        • 2012-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-06
        • 1970-01-01
        相关资源
        最近更新 更多