Question
J'essaie de créer un wrapper pour du code de gestion de matrice clairsemée basé sur C (voir question précédente).Afin d'appeler la fonction Workhorse C, je dois créer une structure qui ressemble à ceci :
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. */
};
Ceux-ci correspondent bien aux emplacements d'un dgCMatrix
matrice clairsemée.Donc, idéalement, je soulignerais simplement les tableaux internes du dgCMatrix
(après avoir vérifié que la fonction C ne jouera pas avec les données [ce que je n'ai pas encore fait]).
Pour *value
, il semble que je pourrai utiliser REALSXP
ou quelque chose pour obtenir un double[]
comme voulu.Mais pour *pointr
et *rowind
, je ne suis pas sûr de la meilleure façon d'accéder à un tableau approprié.Dois-je parcourir les entrées et les copier dans de nouveaux tableaux, en les diffusant au fur et à mesure ?Ou peut Rcpp
fournir du sucre ici ?C'est la première fois que j'utilise vraiment Rcpp et je ne le maîtrise pas encore bien.
Merci.
Modifier:J'ai également des problèmes de liaison que je ne comprends pas :
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
Dois-je créer ma bibliothèque avec des indicateurs de compilation spéciaux ?
Modifier 2 :on dirait mon libargs
Le paramètre n'a aucun effet, donc libsvd
les symboles n’arrivent jamais dans la bibliothèque.Je ne trouve aucun moyen d'inclure des bibliothèques en utilisant cxxfunction()
- voici ce que j'avais essayé, mais les paramètres supplémentaires (empruntés pour des vœux pieux) cfunction()
) sont engloutis en silence :
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)
J'ai l'impression que je m'y prends mal dans tout ce processus, puisque rien ne fonctionne.Quelqu'un me donne un coup de pied dans la bonne direction ?
La solution
J'ai décidé de publier également une requête sur la liste de diffusion Rcpp-devel et j'ai reçu de bons conseils et de l'aide de Dirk et Doug :
http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2011-February/001851.html
Je ne suis toujours pas super-facile avec ce genre de choses, mais j'y arrive.=)
Autres conseils
J'ai fait quelque chose de similaire pour une interface [R]-Smalltalk l'année dernière et je l'ai fait de manière plus générique pour pouvoir transmettre toutes les données dans les deux sens en utilisant des tableaux d'octets :
En C j'ai :
DLLIMPORT void getLengthOfNextMessage(byte* a);
DLLIMPORT void getNextMessage(byte* a);
Dans 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)
}
J'ai commenté l'utilisation des fonctions getNumberOfMessages() et confirmReceived() qui sont spécifiques au problème que je devais résoudre (communications multiples aller-retour).Essentiellement, le code utilise l'argument byte-array pour transférer les informations, d'abord les informations de 4 octets, puis les données réelles.Cela semble moins élégant (même pour moi) que d'utiliser des structures, mais je l'ai trouvé plus générique et je peux me connecter à n'importe quelle DLL, transférant n'importe quel type de données.