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


_______________________________________________
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

Reply via email to