2

我正在尝试为一些基于 C 的稀疏矩阵处理代码制作一个包装器(请参阅上一个问题)。为了调用主力 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[]。但是对于*pointrand *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)

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

4

2 回答 2

1

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

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

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

于 2011-02-28T19:17:58.270 回答
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,传输任何数据类型。

于 2011-02-20T22:45:54.273 回答