Thanks, spot on! On 16 September 2010 19:36, Romain Francois <rom...@r-enthusiasts.com> wrote: > Le 16/09/10 18:32, baptiste auguie a écrit : >> >> Hi, >> >> Thanks for the valuable information and advice. Some comments / questions >> below. >> >> On 16 September 2010 15:49, Romain Francois<rom...@r-enthusiasts.com> >> wrote: >>> >>> Le 16/09/10 15:24, baptiste auguie a écrit : >>>> >>>> Dear list, >>>> >>>> >>>> This is probably not specific to Rcpp but I couldn't find any advice >>>> in the R-exts manual. I am using RcppArmadillo in a package to do some >>>> linear algebra. The C++ code is getting a bit too large to manage in >>>> one file only, I would like to split its content in several files. >>>> It seems possible, but I'm not sure how to deal with the scoping >>>> rules: if a function requires a subroutine defined in another file it >>>> seems to have a scoping problem (the compilation fails with message >>>> "error: ‘xxxx’ was not declared in this scope)". Currently my cpp file >>>> looks like this, >>>> >>>> /////////////////////////////////////////////////// >>>> #include "cda.h" >>>> #include<RcppArmadillo.h> >>>> #include<iostream> >>>> >>>> using namespace Rcpp ; >>>> using namespace RcppArmadillo ; >>>> >>>> using namespace std; >>>> >>>> extern "C" { >>>> >>>> arma::mat foo(const arma::mat& R) { >>>> return(R); >>>> } >>>> >>>> // R wrapper >>>> RCPP_FUNCTION_1(NumericMatrix, test, NumericMatrix IR) >>>> { >>>> arma::mat R = Rcpp::as< arma::mat>(IR); >>>> return wrap( foo(R) ); >>>> } >>>> // other routines >>>> } >>>> /////////////////////////////////////////////////// >>>> >>>> (The actual file is here: >>>> >>>> >>>> https://r-forge.r-project.org/scm/viewvc.php/pkg/cda/src/cda.cpp?diff_format=h&root=photonics&view=log) >>>> >>>> >>>> Are there workarounds / rules to split the content in several files? >>>> >>>> Best regards, >>>> >>>> baptiste >>> >>> Hello, >>> >>> The usual thing is to declare functions in header files, and include >>> these >>> headers from each .cpp file. You then define the functions in .cpp files >>> in >>> any order you like. As long as it is declared, the compiler knows it is >>> coming. >> >> In principle I understand, but in practice I'm a bit stuck with this. >> In my previous header file I only declared RcppExport functions, such >> as >> >> ////////////// >> #ifndef _cda2_CDA2_H >> #define _cda2_CDA2_H >> >> #include<RcppArmadillo.h> >> >> /* void progress_bar(double x, double N); */ >> RcppExport SEXP rotation(SEXP phi, SEXP theta, SEXP psi); >> >> #endif >> >> ////////////// >> >> When I also add internal C++ routines (uncommenting progress_bar >> above) I get errors such as, >> >> ** testing if installed package can be loaded >> Error in dyn.load(file, DLLpath = DLLpath, ...) : >> unable to load shared library >> >> '/Library/Frameworks/R.framework/Resources/library/cda2/libs/x86_64/cda2.so': >> >> dlopen(/Library/Frameworks/R.framework/Resources/library/cda2/libs/x86_64/cda2.so, >> 6): Symbol not found: __Z12progress_bardd >> Referenced from: >> /Library/Frameworks/R.framework/Resources/library/cda2/libs/x86_64/cda2.so >> Expected in: flat namespace >> in >> /Library/Frameworks/R.framework/Resources/library/cda2/libs/x86_64/cda2.so >> ERROR: loading failed > > This is because those are not the same since you enclose everything (bad > practice) into a extern "C" in your .cpp file.
I see. I confess that these things are magic to me. > > If you split things like this, the only place where you need extern "C" (or > RcppExport which is an alias) is in the header > >>> I think you should use RCPP_FUNCTION_* outside of the extern "C" block. > > Actually I think you should not have an extern "C" block at all (see above). > Indeed, I don't need one. >> OK, thanks. >> >>> >>> >>> However, I believe modules now do a better job than the RCPP_* macros, >>> and >>> for example I think you don't need this wrapper: >>> >>> // R level wrapper >>> RCPP_FUNCTION_3(NumericMatrix, rotation, double phi, >>> double theta, double psi) { >>> return wrap(euler(phi, theta, psi)); >>> } >>> >>> You would simply make a module liks this: >>> >>> RCPP_MODULE(aladdin){ >>> using namespace Rcpp ; >>> >>> function( "rotation",&euler ) ; >>> function( "interaction_matrix",&interactionA ) ; >>> } >>> >>> and then on the R side, you grab the module : >>> >>> jasmine<- Module( "aladdin" ) >>> jasmine$rotation( 1, 2, 3 ) >>> jasmine$interaction_matrix( ... ) >>> >> >> It works brilliantly, thanks! It's so much cleaner. > > The rules are: > - for the input, anything Rcpp::as can handle is fine > - for the output, anything Rcpp::wrap can handle is fine > >>> Also note that from the most recent version of RcppArmadillo, you don't >>> need >>> the Rcpp::as anymore to convert a NumericMatrix to an arma::mat, you can >>> just do (I think): >>> >>> arma::mat R = IR ; >>> >> >> A quick test failed, but I'll try again with something more minimal to >> report. > > I think I know what this is. I don't have the right fix right now, and I'll > spare the details, but this will work "in the future". > >> Truth be told, I got lost in the recent discussions on the >> best way to pass a real (complex) matrix from R to Armadillo and I've >> been meaning to go back to this question. > > Sorry for the confusion. I think Rcpp::as is fine. I need a bit more work in > RcppArmadillo for the interchangeability between ComplexVector and cx_mat. Part of the confusion is also on whether one particular technique can save making copies of the object. Thanks again, baptiste > > Perhaps at the next iteration of updating the package. > >> Thanks, >> >> baptiste >> >> >>> Romain > > -- > Romain Francois > Professional R Enthusiast > +33(0) 6 28 91 30 30 > http://romainfrancois.blog.free.fr > |- http://bit.ly/cCmbgg : Rcpp 0.8.6 > |- http://bit.ly/bzoWrs : Rcpp svn revision 2000 > `- http://bit.ly/b8VNE2 : Rcpp at LondonR, oct 5th > > > -- ____________________ Dr. Baptiste Auguié Departamento de Química Física, Universidade de Vigo, Campus Universitario, 36310, Vigo, Spain tel: +34 9868 18617 http://webs.uvigo.es/coloides ____________________ _______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel