سؤال

I'm trying to make a wrapper for some C-based sparse-matrix-handling code (see previous question). In order to call the workhorse C function, I need to create a structure that looks like this:

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. */
};

These correspond nicely to the slots in a dgCMatrix sparse matrix. So ideally I'd just point to the internal arrays in the dgCMatrix (after verifying that the C function won't twiddle with the data [which I haven't done yet]).

For *value, it looks like I'll be able to use REALSXP or something to get a double[] as desired. But for *pointr and *rowind, I'm not sure the best way to get at an appropriate array. Will I need to loop through the entries and copy them to new arrays, casting as I go? Or can Rcpp provide some sugar here? This is the first time I've really used Rcpp much and I'm not well-versed in it yet.

Thanks.

Edit: I'm also having some linking trouble that I don't understand:

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

Do I need to be creating my library with some special compilation flags?

Edit 2: it looks like my libargs parameter has no effect, so libsvd symbols never make it into the library. I can find no way to include libraries using cxxfunction() - here's what I'd tried, but the extra parameters (wishful-thinkingly-borrowed from cfunction()) are silently gobbled up:

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)

I feel like I'm going about this whole process wrong, since nothing's working. Anyone kick me in the right direction?

هل كانت مفيدة؟

المحلول

I decided to also post a query on the Rcpp-devel mailing list, and got some good advice & help from Dirk and Doug:

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

I'm still not super-facile with this stuff, but getting there. =)

نصائح أخرى

I've done something similar for a [R]-Smalltalk-interface last year and went about it more generic to be able to pass all data back-and-forth by using byte-arrays:

In C i have:

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

In 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)
}

I have commented-out the use of the functions getNumberOfMessages() and confirmReceived() which are specific to the problem i had to solve (multiple back-and-forth communication). Essentially, the code uses the argument byte-array to transfer the information, first the 4-byte-long length-info, then the actual data. This seems less elegant (even to me) than to use structs, but i found it to be more generic and i can hook into any dll, transfering any datatype.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top