[Rcpp-devel] split the c++ code in several files

baptiste auguie baptiste.auguie at googlemail.com
Thu Sep 16 18:32:49 CEST 2010


Hi,

Thanks for the valuable information and advice. Some comments / questions below.

On 16 September 2010 15:49, Romain Francois <romain at 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


>
> I think you should use RCPP_FUNCTION_* outside of the extern "C" block.
>

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.

> 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. 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.

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
____________________


More information about the Rcpp-devel mailing list