[Rcpp-devel] Rcpp

Romain Francois romain.francois at dbmail.com
Tue May 11 10:50:09 CEST 2010


Le 10/05/10 20:41, Dirk Eddelbuettel a écrit :
> Hi Jean-Eudes,
>
> Thanks for your interest in Rcpp.
>
> On 10 May 2010 at 14:09, Jean-Eudes Dazard wrote:
> | Here is my beginner?s question:
> |
> | We want to interface an existing C++ subroutine to R. The subroutine can be
> | wrapped up in a C++ program, compiled with standard gcc, and run e.g. under GNU
> | /Linux 2.6.18-128.1.14.el5. It accepts several arguments to it.
> |
> | (i) Using the .Call interface (with SEXP types) seems the best option since we
>
> Yes. Do not use .C() unless you must. .Call() is preferable.

Yep. .C seems simpler at first glance when you go through Writing R 
Extensions, but .Call is better ... especially with Rcpp, as you pass 
down full R objects.

> | want to pass matrices, vectors, scalars to it from R. However, the existing C++
> | subroutine is ~ hundreds of line long. To use Rcpp, it seems unavoidable (yet
> | purpose-defeating) to have to make a lot of changes at the lower C++ level to
> | be able to pass and handle these SEXP types. Is this correct or is there
> | something we missed?

If you send a (small) example (don't send the 100's of lines), it will 
be easier for us to give you clues.

When you have a existing function, it is usually better to keep it as is 
and write a simple .Call compatible wrapper that receives the data from 
R, call you existing function and transform the results back into R 
compatible data.

.Call compatible means:

- the function has C linkage and calling convention, which you can do 
either with the raw extern "C" or with the RcppExport macros in Rcpp
- the function takes between 0 and 65 R objects (SEXP)
- the function returns on R object (again SEXP)

So for example if you function looks like this:

double foobar( int x, double y, std::string z){
	...
}

you'd create a small wrapper like this:

extern "C" SEXP foobar_wrapper( SEXP x, SEXP y, SEXP z){
	double res = foobar(
		Rcpp::as<int>(x),
		Rcpp::as<double>(y),
		Rcpp::as<std::string>( z)
	) ;

	return Rcpp::wrap( res ) ;

}

Rcpp::as<T> works for many types T, as documented in the NEWS file and 
you can see many examples of it in the runit.as.R file in the unitTests 
directory.

Rcpp::wrap also works for many types, and you can also find many 
examples of its usage in the unit tests.



The next version of Rcpp (0.8.0), which we are desperately trying to 
release has further facilities to help with boiler plate wrapping like 
this. You'd write it like this then:

RCPP_FUNCTION_3( double, foobar_wrapper, int x, double y, std::string z){
	return foobar( x, y, z ) ;
}

The first argument of the macro is the returned type, it can be whatever 
type that wrap can handle (int, double, string, vector<T>, 
map<string,T>, ...)

The second argument is the name of the .Call compatible function, you'd 
use this name in R, .Call( "foobar_wrapper", 1L, 2.0, "bla", PACKAGE = 
"yourpackage" )

The remaining arguments are the argument list, which can be whatever 
types that Rcpp::as can handle.


> I believe you missed something. You can pass entire objects (incl matrices)
> down from R to C++ using Rcpp and they arrive as native C++ objects. You can
> pass them back the same way.
>
> So have a look at the vignette Rcpp-introduction included in the recent
> releases (current is 0.7.12) as well as from the CRAN page as well as my
> download page.
>
> There are also numerous examples in the source package in the unit tests.

You can find the unit tests through :

 > system.file( "unitTests", package = "Rcpp" )

They are not really intended for documentation but they give quite a 
good coverage of what you can do.

> | (ii) From the convolution example (see slide #43/112 from Dirk?s recent talk
> | ?Seamless R Extensions
> |
> | using Rcpp and RInside? at UCLA on March 30th), it is necessary to replace the
> | std::vector in C++ to an object of type RcppVector<double>. Do other  containers
> | in C++ (set, list, map etc.) present in the original C++ code need to be
> | replaced whenever they appear in the code, or is it just the containers which
> | appear as arguments in the function call?
>
> I am not sure if you read the whole document but RcppVector is part of the
> so-called 'classic' API where what you desire (STL objects) is supported
> rather well in the 'new' API.  Again, see the vignette.
>
> | (iii) When including Rcpp.h and building a shared object, can problems arise if
> | the version of the gcc compiler used to build the shared object is different
> | from the gcc compiler version that was used to generate the binary for R from
> | the source code?
>
> In theory, yes or maybe. In practice, no.
>
> I have been doing this using shared libraries for Rcpp as well as
> shared-library builds of R since 2005 or 2006, and I have not been bitten. In
> practice one rebuilds every now and then anyway because of new features.

I don't have that much experience as Dirk here, but I would usually stay 
on the safe side and match compilers.

The easier way of course is to write your code as a package and send it 
to cran so that it gets built (for platforms where cran distributes 
binaries) with matching compilers (windows, mac osx, flavors of linux : 
debian, ...). Which platform are you using.

> Hope this helps. Keep the follow-up questions coming.

please do, we are very happy that people start to use Rcpp more and more 
and will definitely try to help.

-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/9aKDM9 : embed images in Rd documents
|- http://tr.im/OIXN : raster images and RImageJ
|- http://tr.im/OcQe : Rcpp 0.7.7




More information about the Rcpp-devel mailing list