EVOLUTION-MANAGER
Edit File: rinside_sample16.cpp
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Simple example showing how expose a C++ function with custom data types // This is a continuation of rinside_sample9.cpp // // Copyright (C) 2014 Christian Authmann #include <iostream> /* * We have a simple data type with two values. */ class Foo { public: Foo(int a, int b) : a(a), b(b) { } ~Foo() { } // The compiler will add the default copy constructor, so this class is copyable. int a, b; }; /* * We define converters between Foo and R objects, see * http://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-extending.pdf */ #include <RcppCommon.h> /* * These template declarations must be after RcppCommon.h and before Rcpp.h * The implementation can follow later, when all of Rcpp/Rinside is available. */ namespace Rcpp { template<> SEXP wrap(const Foo &f); template<> Foo as(SEXP sexp); } #include <Rcpp.h> #include <RInside.h> /* * After including Rcpp/Rinside, we can implement the converters. */ template<> SEXP Rcpp::wrap(const Foo &f) { Rcpp::List list; list["a"] = f.a; list["b"] = f.b; // Like all internal Rcpp datatypes, the List can be autoconverted to a SEXP, so we can just return it. // This is equivalent to: return Rcpp::wrap(list) return list; } template<> Foo Rcpp::as(SEXP sexp) { Rcpp::List list = Rcpp::as<Rcpp::List>(sexp); // Note: This does not work when compiled using clang with Rcpp 0.11.2 and older return Foo( list["a"], list["b"] ); } // a c++ function we wish to expose to R Foo swapFoo(Foo &input) { Foo result(input.b, input.a); return result; } int main(int argc, char *argv[]) { // create an embedded R instance RInside R(argc, argv); // expose the "swapFoo" function in the global environment R["swapFoo"] = Rcpp::InternalFunction( &swapFoo ); // create a foo instance and expose it Foo f(0, 42); R["foo"] = f; // call it, getting another Foo object Foo result = R.parseEvalNT( //"print(foo);" // a=0, b=42 "foo$a = 12;" //"print(foo);" // a=12, b=42 "foo = swapFoo(foo);" //"print(foo);" // a=42, b=12 "foo;" // return the object ); std::cout << " Got result a=" << result.a << ", b=" << result.b << std::endl; std::cout << " Expected a=42, b=12" << std::endl; }