我正在尝试为一些基于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)
我觉得我整个过程都是错误的,因为没有任何工作。有人踢我正确的方向吗?
答案 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,传输任何数据类型。