├── .Rbuildignore ├── .editorconfig ├── .github └── workflows │ └── ci.yaml ├── .gitignore ├── ChangeLog ├── DESCRIPTION ├── NAMESPACE ├── R ├── RInsidePaths.R ├── RcppExports.R └── zzz.R ├── README.md ├── cleanup ├── cleanup.win ├── doxyfile ├── inst ├── NEWS.Rd ├── THANKS ├── examples │ ├── armadillo │ │ ├── GNUmakefile │ │ ├── cmake │ │ │ ├── CMakeLists.txt │ │ │ └── WIN.readme.txt │ │ ├── rinside_arma0.cpp │ │ └── rinside_arma1.cpp │ ├── c_interface │ │ ├── GNUmakefile │ │ ├── hello.c │ │ ├── hello.rb │ │ ├── passdata.c │ │ └── passdata.rb │ ├── eigen │ │ ├── GNUmakefile │ │ ├── cmake │ │ │ ├── CMakeLists.txt │ │ │ └── WIN.readme.txt │ │ ├── rinside_eigen0.cpp │ │ └── rinside_eigen1.cpp │ ├── mpi │ │ ├── GNUmakefile │ │ ├── cmake │ │ │ └── CMakeLists.txt │ │ ├── rinside_mpi_sample0.cpp │ │ ├── rinside_mpi_sample1.cpp │ │ ├── rinside_mpi_sample2.cpp │ │ ├── rinside_mpi_sample3.cpp │ │ └── rinside_mpi_sample4.cpp │ ├── qt │ │ ├── README │ │ ├── cmake │ │ │ └── CMakeLists.txt │ │ ├── main.cpp │ │ ├── qtdensity.cpp │ │ ├── qtdensity.h │ │ └── qtdensity.pro │ ├── sandboxed_server │ │ ├── GNUmakefile │ │ ├── README.md │ │ ├── client │ │ │ ├── callback_helper.h │ │ │ ├── rinsideclient.cpp │ │ │ └── rinsideclient.h │ │ ├── common │ │ │ ├── binarystream.cpp │ │ │ ├── binarystream.h │ │ │ ├── constants.h │ │ │ └── typeid.h │ │ ├── datatypes │ │ │ ├── bar.cpp │ │ │ ├── bar.h │ │ │ ├── bar_rcpp_wrapper_declarations.h │ │ │ ├── bar_rcpp_wrapper_definitions.h │ │ │ ├── foo.cpp │ │ │ ├── foo.h │ │ │ ├── foo_rcpp_wrapper_declarations.h │ │ │ └── foo_rcpp_wrapper_definitions.h │ │ ├── example_client.cpp │ │ ├── example_server.cpp │ │ └── server │ │ │ ├── internalfunction_clone.h │ │ │ ├── rinside_callbacks.h │ │ │ ├── rinsideserver.cpp │ │ │ └── rinsideserver.h │ ├── standard │ │ ├── GNUmakefile │ │ ├── Makefile.win │ │ ├── cmake │ │ │ └── CMakeLists.txt │ │ ├── local │ │ │ ├── rinside_axionator.cpp │ │ │ ├── rinside_issue178.cpp │ │ │ ├── rinside_slava.cpp │ │ │ └── rinside_vertica.cpp │ │ ├── rinside_callbacks0.cpp │ │ ├── rinside_callbacks1.cpp │ │ ├── rinside_interactive0.cpp │ │ ├── rinside_module_sample0.cpp │ │ ├── rinside_sample0.cpp │ │ ├── rinside_sample1.cpp │ │ ├── rinside_sample10.cpp │ │ ├── rinside_sample11.cpp │ │ ├── rinside_sample12.cpp │ │ ├── rinside_sample13.cpp │ │ ├── rinside_sample14.cpp │ │ ├── rinside_sample15.cpp │ │ ├── rinside_sample16.cpp │ │ ├── rinside_sample17.cpp │ │ ├── rinside_sample2.cpp │ │ ├── rinside_sample3.cpp │ │ ├── rinside_sample4.cpp │ │ ├── rinside_sample5.cpp │ │ ├── rinside_sample6.cpp │ │ ├── rinside_sample7.cpp │ │ ├── rinside_sample8.cpp │ │ ├── rinside_sample9.cpp │ │ ├── rinside_test0.cpp │ │ ├── rinside_test1.cpp │ │ └── rinside_test2.cpp │ ├── threads │ │ ├── GNUmakefile │ │ └── boostEx.cpp │ └── wt │ │ ├── GNUmakefile │ │ ├── cmake │ │ └── CMakeLists.txt │ │ ├── wtdensity.cpp │ │ ├── wtdensity.css │ │ ├── wtdensity.xml │ │ └── wtdensityPlain.cpp └── include │ ├── Callbacks.h │ ├── MemBuf.h │ ├── RInside.h │ ├── RInsideCommon.h │ ├── RInsideConfig.h │ └── RInside_C.h ├── local ├── qtdensitySVG.png ├── runDoxygen └── wtdensity.png ├── man └── RInside-package.Rd └── src ├── Makevars ├── Makevars.win ├── MemBuf.cpp ├── RInside.cpp ├── RInside_C.cpp ├── RcppExports.cpp ├── compiler.cpp ├── setenv └── setenv.c └── tools ├── RInsideAutoloads.r ├── RInsideEnvVars.r └── unix2dos.r /.Rbuildignore: -------------------------------------------------------------------------------- 1 | libRInside.a 2 | inst/doc/html 3 | inst/doc/latex 4 | inst/doc/man 5 | inst/doc 6 | inst/lib 7 | inst/examples/qt/Makefile 8 | inst/examples/qt/link.sh 9 | inst/examples/qt/moc_qtdensity.cpp 10 | inst/examples/wt/extkitchen.css 11 | inst/examples/wt/run.sh 12 | configure 13 | configure.win 14 | src/RInsideAutoloads.h 15 | src/RInsideEnvVars.h 16 | inst/include/RInsideAutoloads.h 17 | inst/include/RInsideEnvVars.h 18 | ^\.travis\.yml$ 19 | doxyfile 20 | inst/examples/standard/local 21 | local 22 | ^.*\.Rproj$ 23 | ^\.Rproj\.user$ 24 | ^.*\.tar\.gz 25 | .editorconfig 26 | ^\.github 27 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | # Matches multiple files with brace expansion notation 13 | # 4 space indentation 14 | [*.{c,cpp,h,hpp,R,r}] 15 | indent_style = space 16 | indent_size = 4 17 | 18 | # Tab indentation (no size specified) 19 | [Makefile] 20 | indent_style = tab 21 | 22 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | # Run CI for R using https://eddelbuettel.github.io/r-ci/ 2 | 3 | name: ci 4 | 5 | on: 6 | push: 7 | pull_request: 8 | 9 | env: 10 | _R_CHECK_FORCE_SUGGESTS_: "false" 11 | 12 | jobs: 13 | ci: 14 | strategy: 15 | matrix: 16 | include: 17 | #- {os: macOS-latest} 18 | - {os: ubuntu-latest} 19 | 20 | runs-on: ${{ matrix.os }} 21 | 22 | steps: 23 | - name: Checkout 24 | uses: actions/checkout@v4 25 | 26 | - name: Setup 27 | uses: eddelbuettel/github-actions/r-ci-setup@master 28 | 29 | - name: Bootstrap 30 | run: ./run.sh bootstrap 31 | 32 | - name: Dependencies 33 | run: ./run.sh install_deps 34 | 35 | - name: Test 36 | run: ./run.sh run_tests 37 | 38 | #- name: Coverage 39 | # if: ${{ matrix.os == 'ubuntu-latest' }} 40 | # run: ./run.sh coverage 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | src/*.o 6 | src/*.so 7 | src/*.dll 8 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: RInside 2 | Title: C++ Classes to Embed R in C++ (and C) Applications 3 | Version: 0.2.19 4 | Date: 2025-04-22 5 | Authors@R: c(person("Dirk", "Eddelbuettel", role = c("aut", "cre"), email = "edd@debian.org", 6 | comment = c(ORCID = "0000-0001-6419-907X")), 7 | person("Romain", "Francois", role = "aut", 8 | comment = c(ORCID = "0000-0002-2444-4226")), 9 | person("Lance", "Bachmeier", role = "ctb")) 10 | Description: C++ classes to embed R in C++ (and C) applications 11 | A C++ class providing the R interpreter is offered by this package 12 | making it easier to have "R inside" your C++ application. As R itself 13 | is embedded into your application, a shared library build of R is 14 | required. This works on Linux, OS X and even on Windows provided you 15 | use the same tools used to build R itself. Numerous examples are 16 | provided in the nine subdirectories of the examples/ directory of 17 | the installed package: standard, 'mpi' (for parallel computing), 'qt' 18 | (showing how to embed 'RInside' inside a Qt GUI application), 'wt' 19 | (showing how to build a "web-application" using the Wt toolkit), 20 | 'armadillo' (for 'RInside' use with 'RcppArmadillo'), 'eigen' (for 21 | 'RInside' use with 'RcppEigen'), and 'c_interface' for a basic C 22 | interface and 'Ruby' illustration. The examples use 'GNUmakefile(s)' 23 | with GNU extensions, so a GNU make is required (and will use the 24 | 'GNUmakefile' automatically). 'Doxygen'-generated documentation of 25 | the C++ classes is available at the 'RInside' website as well. 26 | Imports: Rcpp 27 | LinkingTo: Rcpp 28 | URL: https://github.com/eddelbuettel/rinside/, https://dirk.eddelbuettel.com/code/rinside.html 29 | License: GPL (>= 2) 30 | BugReports: https://github.com/eddelbuettel/rinside/issues 31 | MailingList: Please send questions and comments regarding RInside to rcpp-devel@lists.r-forge.r-project.org 32 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | useDynLib("RInside", .registration=TRUE) 2 | importFrom(Rcpp, evalCpp) 3 | -------------------------------------------------------------------------------- /R/RInsidePaths.R: -------------------------------------------------------------------------------- 1 | 2 | ## Use R's internal knowledge of path settings to find the lib/ directory 3 | ## plus optinally an arch-specific directory on system building multi-arch 4 | RInsideLdPath <- function() { 5 | if (nzchar(.Platform$r_arch)) { ## eg amd64, ia64, mips 6 | system.file("lib",.Platform$r_arch,package="RInside") 7 | } else { 8 | system.file("lib",package="RInside") 9 | } 10 | } 11 | 12 | ## Provide linker flags -- i.e. -L/path/to/libRInside -- as well as an 13 | ## optional rpath call needed to tell the Linux dynamic linker about the 14 | ## location. This is not needed on OS X where we encode this as library 15 | ## built time (see src/Makevars) or Windows where we use a static library 16 | ## Updated Jan 2010: We now default to static linking but allow the use 17 | ## of rpath on Linux if static==FALSE has been chosen 18 | ## Note that this is probably being called from LdFlags() 19 | RInsideLdFlags <- function(static=TRUE) { 20 | rinsidedir <- RInsideLdPath() 21 | if (static) { # static is default on Windows and OS X 22 | flags <- paste(rinsidedir, "/libRInside.a", sep="") 23 | if (.Platform$OS.type=="windows") { 24 | flags <- shQuote(flags) 25 | } 26 | } else { # else for dynamic linking 27 | flags <- paste("-L", rinsidedir, " -lRInside", sep="") # baseline setting 28 | if ((.Platform$OS.type == "unix") && # on Linux, we can use rpath to encode path 29 | (length(grep("^linux",R.version$os)))) { 30 | flags <- paste(flags, " -Wl,-rpath,", rinsidedir, sep="") 31 | } 32 | } 33 | invisible(flags) 34 | } 35 | 36 | 37 | ## Provide compiler flags -- i.e. -I/path/to/RInside.h 38 | RInsideCxxFlags <- function() { 39 | path <- system.file( "include", package = "RInside" ) 40 | # if (.Platform$OS.type=="windows") { 41 | # path <- shQuote(path) 42 | # } 43 | sprintf('-I%s', path) 44 | } 45 | 46 | ## Shorter names, and call cat() directly 47 | CxxFlags <- function() { 48 | cat(RInsideCxxFlags()) 49 | } 50 | 51 | 52 | ## Provide compiler flags -- i.e. -I/path/to/RInsideC.h 53 | RInsideCFlags <- function() { 54 | path <- system.file( "include", package = "RInside" ) 55 | # if (.Platform$OS.type=="windows") { 56 | # path <- shQuote(path) 57 | # } 58 | sprintf('-I%s', path) 59 | } 60 | 61 | ## Shorter names, and call cat() directly 62 | CFlags <- function() { 63 | cat(RInsideCFlags()) 64 | } 65 | 66 | 67 | ## LdFlags defaults to static linking on the non-Linux platforms Windows and OS X 68 | LdFlags <- function(static=ifelse(length(grep("^linux",R.version$os))==0, TRUE, FALSE)) { 69 | cat(RInsideLdFlags(static=static)) 70 | } 71 | 72 | 73 | 74 | 75 | # ## Use R's internal knowledge of path settings to find the lib/ directory 76 | # ## plus optinally an arch-specific directory on system building multi-arch 77 | # RInsideLdPath <- function() { 78 | # Rcpp:::packageLibPath( package = "RInside" ) 79 | # } 80 | 81 | ## Provide linker flags -- i.e. -L/path/to/libRInside -- as well as an 82 | ## optional rpath call needed to tell the Linux dynamic linker about the 83 | ## location. This is not needed on OS X where we encode this as library 84 | ## built time (see src/Makevars) or Windows where we use a static library 85 | # RInsideLdFlags <- function(static=Rcpp:::staticLinking()) { 86 | # Rcpp:::packageLdFlags( "RInside", static ) 87 | # } 88 | 89 | ## Provide compiler flags -- i.e. -I/path/to/RInside.h 90 | # RInsideCxxFlags <- function() { 91 | # Rcpp:::includeFlag( package = "RInside" ) 92 | # } 93 | 94 | ## Shorter names, and call cat() directly 95 | # CxxFlags <- function() cat(RInsideCxxFlags()) 96 | # LdFlags <- function(static=Rcpp:::staticLinking()) cat(RInsideLdFlags(static)) 97 | -------------------------------------------------------------------------------- /R/RcppExports.R: -------------------------------------------------------------------------------- 1 | # Generated by using Rcpp::compileAttributes() -> do not edit by hand 2 | # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 3 | 4 | showCompiler <- function() { 5 | invisible(.Call(`_RInside_showCompiler`)) 6 | } 7 | 8 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | #.First.lib <- function(lib, pkg) { 2 | # cat("Loaded RInside.\n") 3 | #} 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## RInside: Easy embedding of R inside C++ (and C) 2 | 3 | [![CI](https://github.com/eddelbuettel/rinside/workflows/ci/badge.svg)](https://github.com/eddelbuettel/rinside/actions?query=workflow%3Aci) 4 | [![License](https://img.shields.io/badge/license-GPL%20%28%3E=%202%29-brightgreen.svg?style=flat)](https://www.gnu.org/licenses/gpl-2.0.html) 5 | [![CRAN](https://www.r-pkg.org/badges/version/RInside)](https://cran.r-project.org/package=RInside) 6 | [![Dependencies](https://tinyverse.netlify.app/badge/RInside)](https://cran.r-project.org/package=RInside) 7 | [![Debian package](https://img.shields.io/debian/v/r-cran-rinside/sid?color=brightgreen)](https://packages.debian.org/sid/r-cran-rinside) 8 | [![Downloads](https://cranlogs.r-pkg.org/badges/RInside?color=brightgreen)](https://cran.r-project.org/package=RInside) 9 | [![Last Commit](https://img.shields.io/github/last-commit/eddelbuettel/rinside)](https://github.com/eddelbuettel/rinside) 10 | 11 | ### About 12 | 13 | The RInside package provides a few classes for seamless embedding of [R](https://www.r-project.org) inside of 14 | C++ applications by relying on [Rcpp](https://www.rcpp.org/). 15 | 16 | ### Examples 17 | 18 | Provided with the package itself are nine subdirectories with examples: from more than a dozen basic command-line examples (in directory 19 | `standard`) to graphical user-interfaces (using both [Qt](https://www.qt.io/) and Wt), linear algebra with 20 | [Armadillo](https://arma.sourceforge.net/) and [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page), parallel computing with MPI to a 21 | sandboxed server, and (since release 0.2.16) a simple (and more limited) interface for embedding insice C applications. 22 | 23 | The simplest example (modulo its header) is [examples/standard/rinside_sample0.cpp](inst/examples/standard/rinside_sample0.cpp) 24 | 25 | ```c++ 26 | #include // for the embedded R via RInside 27 | 28 | int main(int argc, char *argv[]) { 29 | 30 | RInside R(argc, argv); // create an embedded R instance 31 | 32 | R["txt"] = "Hello, world!\n"; // assign a char* (string) to 'txt' 33 | 34 | R.parseEvalQ("cat(txt)"); // eval the init string, ignoring any returns 35 | 36 | exit(0); 37 | } 38 | ``` 39 | The [Qt example directory](https://github.com/eddelbuettel/rinside/tree/master/inst/examples/qt) produces 40 | this application for showing how to use R (to estimate densities) inside a C++ executable (providing the GUI): 41 | 42 | ![](https://github.com/eddelbuettel/rinside/blob/master/local/qtdensitySVG.png) 43 | 44 | The code is portable across operating systems. Similar, the 45 | [Wt example directory](https://github.com/eddelbuettel/rinside/tree/master/inst/examples/wt) 46 | contains this C++-based web application doing the same: 47 | 48 | ![](https://github.com/eddelbuettel/rinside/blob/master/local/wtdensity.png) 49 | 50 | 51 | ### See Also 52 | 53 | The [RInside](https://dirk.eddelbuettel.com/code/rinside.html) web page has 54 | some more details. 55 | 56 | ### Authors 57 | 58 | Dirk Eddelbuettel, Romain Francois, and Lance Bachmeier 59 | 60 | ### License 61 | 62 | GPL (>= 2) 63 | -------------------------------------------------------------------------------- /cleanup: -------------------------------------------------------------------------------- 1 | 2 | rm -vf src/*.o src/*.so inst/lib/*.h \ 3 | src/RInsideEnvVars.h src/RInsideAutoloads.h \ 4 | inst/lib/lib*.so inst/lib/lib*.a \ 5 | Librinside.a 6 | 7 | for d in standard mpi qt wt armadillo eigen threads 8 | do 9 | cd inst/examples/${d} 10 | test -f Makefile && make clean 11 | test -f GNUmakefile && make -f GNUmakefile clean 12 | rm -f *~ 13 | cd ../../.. 14 | done 15 | 16 | rm -rf inst/examples/qt/build 17 | -------------------------------------------------------------------------------- /cleanup.win: -------------------------------------------------------------------------------- 1 | 2 | 3 | rm -vf src/*.o src/*.so inst/lib/*.h \ 4 | inst/lib/lib*.so inst/lib/lib*.a 5 | 6 | cd inst/examples/standard && make -f Makefile.win clean && cd - 7 | ## cd inst/examples/mpi && make clean && cd - 8 | -------------------------------------------------------------------------------- /inst/THANKS: -------------------------------------------------------------------------------- 1 | 2 | Miguel Lechón for finding (and fixing!) a memory-management bug 3 | Daniel F Schwarz for a patch to not override pre-set environment variables 4 | Michael Kane for testing on RHEL 5 | Jan de Leeuw for testing on OS X 6 | Jeffrey Horner for finding and fixing an OS X build bug 7 | Simon Urbanek for OS X (and general) build tips 8 | Richard Holbrey for initial help with the the Windows build 9 | Jianping Hua for contributing two MPI-based examples 10 | Murray Stokely for a patch regarding timing of Rcpp autoloads 11 | James Bates for a patch restoring RInside on Windows 12 | John Brzustowski for a correction to the Windows initialization 13 | Peter Aberline for contributing CMake support for all examples 14 | Theodore Lytras for a patch helping to recover from (some) errors 15 | Spencer Behling for a patch getting the Qt example ready for Qt 5.1 16 | Nicholas Pezolano for a new MPI example 17 | Martin Morgan for a new MPI example 18 | Kevin Ushey for debugging a seg.fault issue post Rcpp 0.11.0 19 | -------------------------------------------------------------------------------- /inst/examples/armadillo/GNUmakefile: -------------------------------------------------------------------------------- 1 | ## -*- mode: make; tab-width: 8; -*- 2 | ## 3 | ## Simple Makefile 4 | 5 | ## comment this out if you need a different version of R, 6 | ## and set set R_HOME accordingly as an environment variable 7 | R_HOME := $(shell R RHOME) 8 | 9 | sources := $(wildcard *.cpp) 10 | programs := $(sources:.cpp=) 11 | 12 | 13 | ## include headers and libraries for R 14 | RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) 15 | RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) 16 | RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) 17 | RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) 18 | 19 | ## if you need to set an rpath to R itself, also uncomment 20 | #RRPATH := -Wl,-rpath,$(R_HOME)/lib 21 | 22 | ## include headers and libraries for Rcpp interface classes 23 | ## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted 24 | RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 25 | RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 26 | 27 | 28 | ## include headers and libraries for RInside embedding classes 29 | RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 30 | RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 31 | 32 | ## RcppArmadillo headers 33 | RCPPARMAINCL := $(shell echo 'RcppArmadillo:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 34 | 35 | ## compiler etc settings used in default make rules 36 | CXX := $(shell $(R_HOME)/bin/R CMD config CXX) 37 | CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) 38 | CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RCPPARMAINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) 39 | LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) 40 | 41 | all: $(programs) 42 | @test -x /usr/bin/strip && strip $^ 43 | 44 | run: $(programs) 45 | @for p in $(programs); do echo; echo "Running $$p:"; ./$$p; done 46 | 47 | clean: 48 | rm -vf $(programs) 49 | rm -vrf *.dSYM 50 | 51 | runAll: 52 | for p in $(programs); do echo "Running $$p"; ./$$p; done 53 | -------------------------------------------------------------------------------- /inst/examples/armadillo/cmake/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.4) 2 | 3 | set (VERBOSE 1) 4 | set (SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) 5 | 6 | execute_process(COMMAND R RHOME 7 | OUTPUT_VARIABLE R_HOME) 8 | 9 | file(GLOB sources ${SRC_DIR}/*.cpp) 10 | 11 | set(NUM_TRUNC_CHARS 2) 12 | 13 | set (RPATH "R") 14 | set (RSCRIPT_PATH "Rscript") 15 | 16 | if (CMAKE_HOST_WIN32) 17 | execute_process(COMMAND ${RSCRIPT_PATH} -e "cat(.Platform$r_arch)" 18 | OUTPUT_VARIABLE R_ARCH) 19 | 20 | execute_process(COMMAND R --arch ${R_ARCH} RHOME 21 | OUTPUT_VARIABLE R_HOME) 22 | 23 | string(REPLACE "\\" "/" R_HOME ${R_HOME}) 24 | 25 | set (RPATH ${R_HOME}/bin/R) 26 | endif() 27 | 28 | set (RCPPFLAGS_CMD " ${RPATH} " " CMD " " config " " --cppflags ") 29 | 30 | execute_process(COMMAND ${RPATH} CMD config --cppflags 31 | OUTPUT_VARIABLE RCPPFLAGS) 32 | 33 | if (CMAKE_HOST_WIN32) 34 | if (${RCPPFLAGS} MATCHES "[-][I]([^ ;])+") 35 | set (RCPPFLAGS ${CMAKE_MATCH_0}) 36 | endif() 37 | endif() 38 | 39 | string(SUBSTRING ${RCPPFLAGS} ${NUM_TRUNC_CHARS} -1 RCPPFLAGS) 40 | include_directories(${RCPPFLAGS}) 41 | 42 | execute_process(COMMAND ${RPATH} CMD config --ldflags 43 | OUTPUT_VARIABLE RLDFLAGS) 44 | string(LENGTH ${RLDFLAGS} RLDFLAGS_LEN) 45 | 46 | if (${RLDFLAGS} MATCHES "[-][L]([^ ;])+") 47 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_L) 48 | string(STRIP ${RLDFLAGS_L} RLDFLAGS_L ) 49 | link_directories(${RLDFLAGS_L} ) 50 | endif() 51 | 52 | if (${RLDFLAGS} MATCHES "[-][l]([^;])+") 53 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_l) 54 | string(STRIP ${RLDFLAGS_l} RLDFLAGS_l ) 55 | endif() 56 | 57 | execute_process(COMMAND ${RSCRIPT_PATH} -e "Rcpp:::CxxFlags()" 58 | OUTPUT_VARIABLE RCPPINCL) 59 | string(SUBSTRING ${RCPPINCL} ${NUM_TRUNC_CHARS} -1 RCPPINCL) 60 | include_directories(${RCPPINCL}) 61 | 62 | execute_process(COMMAND ${RSCRIPT_PATH} -e "Rcpp:::LdFlags()" 63 | OUTPUT_VARIABLE RCPPLIBS) 64 | 65 | execute_process(COMMAND ${RSCRIPT_PATH} -e "RInside:::CxxFlags()" 66 | OUTPUT_VARIABLE RINSIDEINCL) 67 | string(SUBSTRING ${RINSIDEINCL} ${NUM_TRUNC_CHARS} -1 RINSIDEINCL) 68 | include_directories(${RINSIDEINCL}) 69 | message(${RINSIDEINCL}) 70 | 71 | execute_process(COMMAND ${RSCRIPT_PATH} -e "RInside:::LdFlags()" 72 | OUTPUT_VARIABLE RINSIDELIBS) 73 | 74 | execute_process(COMMAND ${RSCRIPT_PATH} -e "RcppArmadillo:::CxxFlags()" 75 | OUTPUT_VARIABLE RCPPARMADILLOINCL) 76 | 77 | string(LENGTH ${RCPPARMADILLOINCL} INCLLENGTH) 78 | math(EXPR INCLLENGTH "${INCLLENGTH}-4") 79 | 80 | string(SUBSTRING ${RCPPARMADILLOINCL} 3 ${INCLLENGTH} RCPPARMADILLOINCL) 81 | include_directories(${RCPPARMADILLOINCL}) 82 | 83 | if (CMAKE_HOST_WIN32) 84 | string(LENGTH "libRcpp.a" lenRcppName) 85 | string(LENGTH ${RCPPLIBS} lenRcppFQName) 86 | 87 | math(EXPR RLibPathLen ${lenRcppFQName}-${lenRcppName}-1) 88 | string(SUBSTRING ${RCPPLIBS} 0 ${RLibPathLen} RCPPLIBS_L) 89 | link_directories(${RCPPLIBS_L}) 90 | 91 | math(EXPR RLibPathLen ${RLibPathLen}+1) 92 | string(SUBSTRING ${RCPPLIBS} ${RLibPathLen} -1 RCPPLIBS_l) 93 | 94 | #Remove the quotes 95 | string(SUBSTRING ${RINSIDELIBS} 1 -1 RINSIDELIBS) 96 | string(LENGTH ${RINSIDELIBS} lenRInsideFQNameLen) 97 | math(EXPR lenRInsideFQNameLen ${lenRInsideFQNameLen}-1) 98 | string(SUBSTRING ${RINSIDELIBS} 0 ${lenRInsideFQNameLen} RINSIDELIBS) 99 | 100 | string(LENGTH "libRInside.a" lenRInsideName) 101 | string(LENGTH ${RINSIDELIBS} lenRInsideFQName) 102 | 103 | math(EXPR RLibPathLen ${lenRInsideFQName}-${lenRInsideName}-1) 104 | string(SUBSTRING ${RINSIDELIBS} 0 ${RLibPathLen} RINSIDELIBS_L) 105 | 106 | math(EXPR RLibPathLen ${RLibPathLen}+1) 107 | string(SUBSTRING ${RINSIDELIBS} ${RLibPathLen} -1 RINSIDELIBS_l) 108 | 109 | link_directories(${RINSIDELIBS_L}) 110 | 111 | set ( BLAS_LIBS ${CMAKE_CURRENT_SOURCE_DIR}/libblas.lib) 112 | set ( LAPACK_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/liblapack.lib) 113 | link_directories(${CMAKE_CURRENT_SOURCE_DIR}) 114 | 115 | else() 116 | if (${RCPPLIBS} MATCHES "[-][L]([^ ;])+") 117 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_L) 118 | link_directories(${RCPPLIBS_L} ) 119 | endif() 120 | 121 | if (${RCPPLIBS} MATCHES "[-][l][R]([^;])+") 122 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_l) 123 | endif() 124 | 125 | if (${RINSIDELIBS} MATCHES "[-][L]([^ ;])+") 126 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_L) 127 | link_directories(${RINSIDELIBS_L}) 128 | endif() 129 | 130 | if (${RINSIDELIBS} MATCHES "[-][l][R]([^;])+") 131 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_l) 132 | endif() 133 | 134 | # If the faster 'gold' linker is used, to avoid complaints about undefined symbol 135 | SET(CMAKE_FIND_LIBRARY_SUFFIXES_SAVED ${CMAKE_FIND_LIBRARY_SUFFIXES}) # Backup 136 | LIST(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".so.3") 137 | FIND_LIBRARY(BLAS_LIBRARY blas) 138 | SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAVED}) # Restore 139 | LIST(APPEND EXTRA_LIBRARIES ${BLAS_LIBRARY}) 140 | 141 | FIND_LIBRARY(LAPACK_LIBRARY lapack) 142 | endif() 143 | 144 | execute_process(COMMAND ${RPATH} CMD config CXXFLAGS 145 | OUTPUT_VARIABLE RCXXFLAGS) 146 | 147 | execute_process(COMMAND ${RPATH} CMD config BLAS_LIBS 148 | OUTPUT_VARIABLE RBLAS) 149 | 150 | execute_process(COMMAND ${RPATH} CMD config LAPACK_LIBS 151 | OUTPUT_VARIABLE RLAPACK) 152 | 153 | set(CMAKE_CXX_FLAGS "-W -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}") 154 | 155 | if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR 156 | CMAKE_BUILD_TYPE STREQUAL "RelWithDebugInfo" ) 157 | add_definitions("-DDEBUG") 158 | elseif ( CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) 159 | add_definitions("-O3") 160 | endif() 161 | 162 | message ("cmake_cxx_flags" ${CMAKE_CXX_FLAGS}) 163 | 164 | foreach (next_SOURCE ${sources}) 165 | get_filename_component(source_name ${next_SOURCE} NAME_WE) 166 | add_executable( ${source_name} ${next_SOURCE} ) 167 | 168 | target_link_libraries(${source_name} ${RLDFLAGS_l}) 169 | target_link_libraries(${source_name} ${BLAS_LIBS}) 170 | target_link_libraries(${source_name} ${LAPACK_LIBS}) 171 | target_link_libraries(${source_name} ${RINSIDELIBS_l}) 172 | target_link_libraries(${source_name} ${RCPPLIBS_l}) 173 | target_link_libraries(${source_name} ${EXTRA_LIBRARIES}) 174 | 175 | target_link_libraries(${source_name} ${LAPACK_LIBRARY}) 176 | 177 | endforeach (next_SOURCE ${sources}) 178 | 179 | -------------------------------------------------------------------------------- /inst/examples/armadillo/cmake/WIN.readme.txt: -------------------------------------------------------------------------------- 1 | 2 | Building these examples on Windows is a bit more difficult than on Linux. 3 | 4 | * Put R in the path: 5 | C:\R\R-2.1X.X\bin 6 | C:\R\R-2.1X.X\bin\i386 7 | 8 | * Add required environment variables: 9 | R_HOME C:\R\R-2.1X.X 10 | CYGWIN nodosfilewarning 11 | 12 | * Then libpack and libblas for Windows needed to be obtained from: 13 | 14 | http://icl.cs.utk.edu/lapack-for-windows/lapack/index.html#libraries_mingw 15 | 16 | * The CMakeLists.txt files expect the liblapack.lib and libblas.lib files to be in the same directory as themselves for the Windows build. You can edit lines 7 and 8 of the the CMakeLists.txt files if they are not in this location. 17 | 18 | * I generally build in a 'build' directly below cmake: 19 | mkdir build 20 | cd build 21 | cmake -G "Unix Makefiles" ../. 22 | make 23 | 24 | To run these example there are further DLL dependencies required not installed by RTools: 25 | 26 | libgcc_s_dw2-1.dll 27 | libgfortran.dll 28 | libquadmath-0.dll 29 | liblapack.dll 30 | 31 | I was able to grab these by installing MinGW from: http://sourceforge.net/projects/mingw/files/MinGW/Base/gcc/Version4/ 32 | Use the version that matches the gcc version that is installed by RTools. 33 | 34 | Once installed, either add their location to the PATH, or copy them to either the same directory as the example executable, or put them in the windows/system32 folder. 35 | 36 | Peter 37 | peter dot aberline at gmail dot com 38 | -------------------------------------------------------------------------------- /inst/examples/armadillo/rinside_arma0.cpp: -------------------------------------------------------------------------------- 1 | // -*- c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // Simple example using Armadillo classes 4 | // 5 | // Copyright (C) 2012 - 2013 Dirk Eddelbuettel and Romain Francois 6 | 7 | #include // for Armadillo as well as Rcpp 8 | #include // for the embedded R via RInside 9 | 10 | int main(int argc, char *argv[]) { 11 | 12 | RInside R(argc, argv); // create an embedded R instance 13 | 14 | std::string cmd = "diag(3)"; // create a Matrix in r 15 | 16 | arma::mat m = Rcpp::as(R.parseEval(cmd)); // parse, eval + return result 17 | 18 | std::cout << m << std::endl; // and use Armadillo i/o 19 | 20 | exit(0); 21 | } 22 | -------------------------------------------------------------------------------- /inst/examples/armadillo/rinside_arma1.cpp: -------------------------------------------------------------------------------- 1 | // -*- c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // Simple example using Armadillo on matrix data generated in R 4 | // 5 | // Copyright (C) 2012 - 2013 Dirk Eddelbuettel and Romain Francois 6 | 7 | #include // for Armadillo as well as Rcpp 8 | #include // for the embedded R via RInside 9 | 10 | int main(int argc, char *argv[]) { 11 | 12 | RInside R(argc, argv); // create an embedded R instance 13 | 14 | std::string cmd = "set.seed(42); matrix(rnorm(9),3,3)"; // create a random Matrix in r 15 | 16 | arma::mat m = Rcpp::as(R.parseEval(cmd)); // parse, eval + return result 17 | arma::mat n = m.t() * m; 18 | double nacc = arma::accu(n); 19 | double nrnk = arma::rank(n); 20 | 21 | m.print("Initial Matrix m"); // initial random matrix 22 | n.print("Product n = m' * m"); // product of m' * m 23 | std::cout << "accu(n) " << nacc << " " 24 | << "rank(n) " << nrnk << std::endl; // accu() and rank() 25 | 26 | exit(0); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /inst/examples/c_interface/GNUmakefile: -------------------------------------------------------------------------------- 1 | # Basic R extensions info 2 | R_HOME := $(shell R RHOME) 3 | RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) 4 | 5 | # Header files required by Rcpp 6 | RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) 7 | 8 | # Location of RInsideC.h 9 | RINSIDECINCL := $(shell echo 'RInside:::CFlags()' | $(R_HOME)/bin/R --vanilla --slave) 10 | 11 | # Location of RInsideC library 12 | RINSIDECLIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 13 | 14 | # C compiler 15 | CC := $(shell $(R_HOME)/bin/R CMD config CC) 16 | 17 | FLAGS := $(RLDFLAGS) $(RCPPFLAGS) $(RINSIDECLIBS) $(RINSIDECINCL) 18 | 19 | hello: 20 | $(CC) hello.c $(FLAGS) -o hello 21 | ./hello 22 | 23 | pass: 24 | $(CC) passdata.c $(FLAGS) -o passdata 25 | ./passdata 26 | -------------------------------------------------------------------------------- /inst/examples/c_interface/hello.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | setupRinC(); 5 | evalQuietlyInR("print('Hello, World')"); 6 | teardownRinC(); 7 | } 8 | -------------------------------------------------------------------------------- /inst/examples/c_interface/hello.rb: -------------------------------------------------------------------------------- 1 | #~ Hello World in Ruby 2 | #~ Printing is done by R, not Ruby 3 | require 'ffi' 4 | 5 | module R 6 | extend FFI::Library 7 | libdir = `Rscript -e \'cat(find.package("RInside"))\'` 8 | ffi_lib "#{libdir}/lib/libRInside.so" 9 | attach_function :setupRinC, [ ], :void 10 | attach_function :evalQuietlyInR, [ :string ], :void 11 | attach_function :teardownRinC, [ ], :void 12 | end 13 | 14 | R.setupRinC() 15 | R.evalQuietlyInR("print('Hello from R!')") 16 | R.teardownRinC() 17 | -------------------------------------------------------------------------------- /inst/examples/c_interface/passdata.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | setupRinC(); 5 | evalQuietlyInR("y <- 3"); 6 | evalQuietlyInR("z <- 2.5"); 7 | evalQuietlyInR("print(y*z)"); 8 | evalQuietlyInR("y <- rnorm(10)"); 9 | evalQuietlyInR("print(y)"); 10 | SEXP vec = evalInR("y"); 11 | Rf_PrintValue(vec); 12 | printf("%f\n", REAL(vec)[4]); 13 | teardownRinC(); 14 | } 15 | -------------------------------------------------------------------------------- /inst/examples/c_interface/passdata.rb: -------------------------------------------------------------------------------- 1 | require 'ffi' 2 | 3 | module R 4 | extend FFI::Library 5 | libdir = `Rscript -e \'cat(find.package("RInside"))\'` 6 | ffi_lib "#{libdir}/lib/libRInside.so" 7 | attach_function :setupRinC, [ ], :void 8 | attach_function :evalQuietlyInR, [ :string ], :void 9 | attach_function :evalInR, [ :string ], :pointer 10 | attach_function :teardownRinC, [ ], :void 11 | end 12 | 13 | module Rlib 14 | extend FFI::Library 15 | ffi_lib "libR.so" 16 | attach_function :Rf_PrintValue, [ :pointer ], :void 17 | attach_function :REAL, [ :pointer ], :pointer 18 | end 19 | 20 | #~ Create a variable and set its value in R 21 | #~ Pass the SEXP from R to Ruby 22 | #~ Call Rf_PrintValue from Ruby 23 | R.setupRinC() 24 | R.evalQuietlyInR("y <- 4.5") 25 | Rlib.Rf_PrintValue(R.evalInR("y")) 26 | 27 | #~ Obtain a pointer in Ruby to the data array underlying 28 | #~ the v created in R 29 | R.evalQuietlyInR("v <- c(1.5, 3.4, 4.2)") 30 | puts Rlib.REAL(R.evalInR("v")) 31 | R.teardownRinC() 32 | -------------------------------------------------------------------------------- /inst/examples/eigen/GNUmakefile: -------------------------------------------------------------------------------- 1 | ## -*- mode: make; tab-width: 8; -*- 2 | ## 3 | ## Simple Makefile 4 | 5 | ## comment this out if you need a different version of R, 6 | ## and set set R_HOME accordingly as an environment variable 7 | R_HOME := $(shell R RHOME) 8 | 9 | sources := $(wildcard *.cpp) 10 | programs := $(sources:.cpp=) 11 | 12 | 13 | ## include headers and libraries for R 14 | RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) 15 | RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) 16 | RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) 17 | RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) 18 | 19 | ## if you need to set an rpath to R itself, also uncomment 20 | #RRPATH := -Wl,-rpath,$(R_HOME)/lib 21 | 22 | ## include headers and libraries for Rcpp interface classes 23 | ## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted 24 | RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 25 | RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 26 | 27 | 28 | ## include headers and libraries for RInside embedding classes 29 | RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 30 | RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 31 | 32 | ## RcppEigen headers 33 | RCPPEIGENINCL := $(shell echo 'cat(paste("-I", system.file("include", package = "RcppEigen"), sep = ""))' | $(R_HOME)/bin/R --vanilla --slave) 34 | 35 | ## compiler etc settings used in default make rules 36 | CXX := $(shell $(R_HOME)/bin/R CMD config CXX) 37 | CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) 38 | CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RCPPEIGENINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) 39 | LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) 40 | 41 | all: $(programs) 42 | @test -x /usr/bin/strip && strip $^ 43 | 44 | run: $(programs) 45 | @for p in $(programs); do echo; echo "Running $$p:"; ./$$p; done 46 | 47 | clean: 48 | rm -vf $(programs) 49 | rm -vrf *.dSYM 50 | 51 | runAll: 52 | for p in $(programs); do echo "Running $$p"; ./$$p; done 53 | -------------------------------------------------------------------------------- /inst/examples/eigen/cmake/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.4) 2 | 3 | set (VERBOSE 1) 4 | set (SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) 5 | 6 | execute_process(COMMAND R RHOME 7 | OUTPUT_VARIABLE R_HOME) 8 | 9 | file(GLOB sources ${SRC_DIR}/*.cpp) 10 | 11 | set(NUM_TRUNC_CHARS 2) 12 | 13 | set (RPATH "R") 14 | set (RSCRIPT_PATH "Rscript") 15 | 16 | if (CMAKE_HOST_WIN32) 17 | execute_process(COMMAND ${RSCRIPT_PATH} -e "cat(.Platform$r_arch)" 18 | OUTPUT_VARIABLE R_ARCH) 19 | 20 | execute_process(COMMAND ${RPATH} --arch ${R_ARCH} RHOME 21 | OUTPUT_VARIABLE R_HOME) 22 | 23 | string(REPLACE "\\" "/" R_HOME ${R_HOME}) 24 | 25 | set (RPATH ${R_HOME}/bin/R) 26 | endif() 27 | 28 | set (RCPPFLAGS_CMD " ${RPATH} " " CMD " " config " " --cppflags ") 29 | 30 | execute_process(COMMAND ${RPATH} CMD config --cppflags 31 | OUTPUT_VARIABLE RCPPFLAGS) 32 | 33 | if (CMAKE_HOST_WIN32) 34 | if (${RCPPFLAGS} MATCHES "[-][I]([^ ;])+") 35 | set (RCPPFLAGS ${CMAKE_MATCH_0}) 36 | endif() 37 | endif() 38 | 39 | string(SUBSTRING ${RCPPFLAGS} ${NUM_TRUNC_CHARS} -1 RCPPFLAGS) 40 | include_directories(${RCPPFLAGS}) 41 | 42 | execute_process(COMMAND R CMD config --ldflags 43 | OUTPUT_VARIABLE RLDFLAGS) 44 | string(LENGTH ${RLDFLAGS} RLDFLAGS_LEN) 45 | 46 | if (${RLDFLAGS} MATCHES "[-][L]([^ ;])+") 47 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_L) 48 | string(STRIP ${RLDFLAGS_L} RLDFLAGS_L ) 49 | link_directories(${RLDFLAGS_L} ) 50 | endif() 51 | 52 | if (${RLDFLAGS} MATCHES "[-][l]([^;])+") 53 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_l) 54 | string(STRIP ${RLDFLAGS_l} RLDFLAGS_l ) 55 | endif() 56 | 57 | execute_process(COMMAND Rscript -e "Rcpp:::CxxFlags()" 58 | OUTPUT_VARIABLE RCPPINCL) 59 | string(SUBSTRING ${RCPPINCL} ${NUM_TRUNC_CHARS} -1 RCPPINCL) 60 | include_directories(${RCPPINCL}) 61 | 62 | execute_process(COMMAND Rscript -e "Rcpp:::LdFlags()" 63 | OUTPUT_VARIABLE RCPPLIBS) 64 | 65 | execute_process(COMMAND Rscript -e "RInside:::CxxFlags()" 66 | OUTPUT_VARIABLE RINSIDEINCL) 67 | string(SUBSTRING ${RINSIDEINCL} ${NUM_TRUNC_CHARS} -1 RINSIDEINCL) 68 | include_directories(${RINSIDEINCL}) 69 | 70 | execute_process(COMMAND Rscript -e "RInside:::LdFlags()" 71 | OUTPUT_VARIABLE RINSIDELIBS) 72 | 73 | execute_process(COMMAND Rscript -e "cat(paste('-I', system.file('include', package = 'RcppEigen'), sep=''))" OUTPUT_VARIABLE RCPPEIGENINCL) 74 | 75 | string(SUBSTRING ${RCPPEIGENINCL} ${NUM_TRUNC_CHARS} -1 RCPPEIGENINCL) 76 | include_directories(${RCPPEIGENINCL}) 77 | 78 | if (CMAKE_HOST_WIN32) 79 | string(LENGTH "libRcpp.a" lenRcppName) 80 | string(LENGTH ${RCPPLIBS} lenRcppFQName) 81 | 82 | math(EXPR RLibPathLen ${lenRcppFQName}-${lenRcppName}-1) 83 | string(SUBSTRING ${RCPPLIBS} 0 ${RLibPathLen} RCPPLIBS_L) 84 | link_directories(${RCPPLIBS_L}) 85 | 86 | math(EXPR RLibPathLen ${RLibPathLen}+1) 87 | string(SUBSTRING ${RCPPLIBS} ${RLibPathLen} -1 RCPPLIBS_l) 88 | 89 | #Remove the quotes 90 | string(SUBSTRING ${RINSIDELIBS} 1 -1 RINSIDELIBS) 91 | string(LENGTH ${RINSIDELIBS} lenRInsideFQNameLen) 92 | math(EXPR lenRInsideFQNameLen ${lenRInsideFQNameLen}-1) 93 | string(SUBSTRING ${RINSIDELIBS} 0 ${lenRInsideFQNameLen} RINSIDELIBS) 94 | 95 | string(LENGTH "libRInside.a" lenRInsideName) 96 | string(LENGTH ${RINSIDELIBS} lenRInsideFQName) 97 | 98 | math(EXPR RLibPathLen ${lenRInsideFQName}-${lenRInsideName}-1) 99 | string(SUBSTRING ${RINSIDELIBS} 0 ${RLibPathLen} RINSIDELIBS_L) 100 | 101 | math(EXPR RLibPathLen ${RLibPathLen}+1) 102 | string(SUBSTRING ${RINSIDELIBS} ${RLibPathLen} -1 RINSIDELIBS_l) 103 | 104 | link_directories(${RINSIDELIBS_L}) 105 | 106 | set ( BLAS_LIBS ${CMAKE_CURRENT_SOURCE_DIR}/libblas.lib) 107 | set ( LAPACK_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/liblapack.lib) 108 | link_directories(${CMAKE_CURRENT_SOURCE_DIR}) 109 | else() 110 | if (${RCPPLIBS} MATCHES "[-][L]([^ ;])+") 111 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_L) 112 | link_directories(${RCPPLIBS_L} ) 113 | endif() 114 | 115 | if (${RCPPLIBS} MATCHES "[-][l][R]([^;])+") 116 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_l) 117 | endif() 118 | 119 | if (${RINSIDELIBS} MATCHES "[-][L]([^ ;])+") 120 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_L) 121 | link_directories(${RINSIDELIBS_L}) 122 | endif() 123 | 124 | if (${RINSIDELIBS} MATCHES "[-][l][R]([^;])+") 125 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_l) 126 | endif() 127 | 128 | # If the faster 'gold' linker is used, to avoid complaints about undefined symbol 129 | SET(CMAKE_FIND_LIBRARY_SUFFIXES_SAVED ${CMAKE_FIND_LIBRARY_SUFFIXES}) # Backup 130 | LIST(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".so.3") 131 | FIND_LIBRARY(BLAS_LIBRARY blas) 132 | SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAVED}) # Restore 133 | LIST(APPEND EXTRA_LIBRARIES ${BLAS_LIBRARY}) 134 | endif() 135 | 136 | execute_process(COMMAND R CMD config CXXFLAGS 137 | OUTPUT_VARIABLE RCXXFLAGS) 138 | 139 | execute_process(COMMAND R CMD config BLAS_LIBS 140 | OUTPUT_VARIABLE RBLAS) 141 | 142 | execute_process(COMMAND R CMD config LAPACK_LIBS 143 | OUTPUT_VARIABLE RLAPACK) 144 | 145 | 146 | FIND_LIBRARY(LAPACK_LIBRARY lapack) 147 | 148 | set(CMAKE_CXX_FLAGS "-W -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}") 149 | 150 | if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR 151 | CMAKE_BUILD_TYPE STREQUAL "RelWithDebugInfo" ) 152 | add_definitions("-DDEBUG") 153 | elseif ( CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) 154 | add_definitions("-O3") 155 | endif() 156 | 157 | foreach (next_SOURCE ${sources}) 158 | get_filename_component(source_name ${next_SOURCE} NAME_WE) 159 | add_executable( ${source_name} ${next_SOURCE} ) 160 | 161 | target_link_libraries(${source_name} ${RLDFLAGS_l}) 162 | target_link_libraries(${source_name} ${BLAS_LIBS}) 163 | target_link_libraries(${source_name} ${LAPACK_LIBS}) 164 | target_link_libraries(${source_name} ${RINSIDELIBS_l}) 165 | target_link_libraries(${source_name} ${RCPPLIBS_l}) 166 | target_link_libraries(${source_name} ${EXTRA_LIBRARIES}) 167 | target_link_libraries(${source_name} ${LAPACK_LIBRARY}) 168 | endforeach (next_SOURCE ${sources}) 169 | 170 | -------------------------------------------------------------------------------- /inst/examples/eigen/cmake/WIN.readme.txt: -------------------------------------------------------------------------------- 1 | 2 | Building these examples on Windows is a bit more difficult than on Linux. 3 | 4 | * Put R in the path: 5 | C:\R\R-2.1X.X\bin 6 | C:\R\R-2.1X.X\bin\i386 7 | 8 | * Add required environment variables: 9 | R_HOME C:\R\R-2.1X.X 10 | CYGWIN nodosfilewarning 11 | 12 | * Then libpack and libblas for Windows needed to be obtained from: 13 | 14 | http://icl.cs.utk.edu/lapack-for-windows/lapack/index.html#libraries_mingw 15 | 16 | * The CMakeLists.txt files expect the liblapack.lib and libblas.lib files to be in the same directory as themselves for the Windows build. You can edit lines 7 and 8 of the the CMakeLists.txt files if they are not in this location. 17 | 18 | * I generally build in a 'build' directly below cmake: 19 | mkdir build 20 | cd build 21 | cmake -G "Unix Makefiles" ../. 22 | make 23 | 24 | To run these example there are further DLL dependencies required not installed by RTools: 25 | 26 | libgcc_s_dw2-1.dll 27 | libgfortran.dll 28 | libquadmath-0.dll 29 | liblapack.dll 30 | 31 | I was able to grab these by installing MinGW from: http://sourceforge.net/projects/mingw/files/MinGW/Base/gcc/Version4/ 32 | Use the version that matches the gcc version that is installed by RTools. 33 | 34 | Once installed, either add their location to the PATH, or copy them to either the same directory as the example executable, or put them in the windows/system32 folder. 35 | 36 | Peter 37 | peter dot aberline at gmail dot com 38 | -------------------------------------------------------------------------------- /inst/examples/eigen/rinside_eigen0.cpp: -------------------------------------------------------------------------------- 1 | // -*- c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // Simple example using Eigen classes 4 | // 5 | // Copyright (C) 2012 Dirk Eddelbuettel and Romain Francois 6 | 7 | #include // for the embedded R via RInside 8 | #include 9 | 10 | int main(int argc, char *argv[]) { 11 | 12 | RInside R(argc, argv); // create an embedded R instance 13 | 14 | std::string cmd = "diag(3)"; // create a Matrix in r 15 | 16 | const Eigen::Map m = // parse, eval + return result 17 | Rcpp::as >(R.parseEval(cmd)); 18 | 19 | std::cout << m << std::endl; // and use Eigen i/o 20 | 21 | exit(0); 22 | } 23 | -------------------------------------------------------------------------------- /inst/examples/eigen/rinside_eigen1.cpp: -------------------------------------------------------------------------------- 1 | // -*- c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // Simple example using Eigen classes on matrix data generated in R 4 | // 5 | // Copyright (C) 2012 Dirk Eddelbuettel and Romain Francois 6 | 7 | #include // for the embedded R via RInside 8 | #include 9 | 10 | int main(int argc, char *argv[]) { 11 | 12 | RInside R(argc, argv); // create an embedded R instance 13 | 14 | std::string cmd = "set.seed(42); matrix(rnorm(9),3,3)"; // create a random Matrix in r 15 | 16 | const Eigen::Map m = // parse, eval + return result 17 | Rcpp::as >(R.parseEval(cmd)); 18 | Eigen::MatrixXd n = m.transpose() * m; 19 | Eigen::ColPivHouseholderQR nqr(n); 20 | 21 | std::cout << "Initial Matrix m\n" << m << std::endl; 22 | std::cout << "Product n = m' * m\n" << n << std::endl; 23 | std::cout << "n.sum() " << n.sum() << std::endl; 24 | std::cout << "nrq.rank() " << nqr.rank() << std::endl; 25 | 26 | exit(0); 27 | } 28 | -------------------------------------------------------------------------------- /inst/examples/mpi/GNUmakefile: -------------------------------------------------------------------------------- 1 | ## -*- mode: make; tab-width: 8; -*- 2 | ## 3 | ## Simple Makefile for MPI use of RInside 4 | ## 5 | ## TODO: 6 | ## proper configure for non-Debian file locations, [ Done ] 7 | ## allow RHOME to be set for non-default R etc [ Done ] 8 | 9 | ## comment this out if you need a different version of R, 10 | ## and set set R_HOME accordingly as an environment variable 11 | R_HOME := $(shell R RHOME) 12 | 13 | sources := $(wildcard *.cpp) 14 | programs := $(sources:.cpp=) 15 | 16 | 17 | # OpenMPI header and libraries 18 | MPICPPFLAGS := $(shell mpic++ -showme:compile) 19 | MPILIBS := $(shell mpic++ -showme:link) 20 | 21 | ## include headers and libraries for R 22 | RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) 23 | RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) 24 | RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) 25 | RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) 26 | 27 | 28 | ## include headers and libraries for Rcpp interface classes 29 | ## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted 30 | RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 31 | RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 32 | 33 | 34 | ## include headers and libraries for RInside embedding classes 35 | RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 36 | RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 37 | 38 | 39 | ## compiler etc settings used in default make rules 40 | CXX := $(shell $(R_HOME)/bin/R CMD config CXX) 41 | CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) 42 | CXXFLAGS := $(MPICPPFLAGS) $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) 43 | LDLIBS := $(MPILIBS) $(RLDFLAGS) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) 44 | 45 | all : $(programs) 46 | @test -x /usr/bin/strip && strip $^ 47 | 48 | run : $(programs) 49 | @test -x /usr/bin/mpirun && for p in $(programs); do echo; echo "Running $$p:"; mpirun -n 4 ./$$p; done 50 | 51 | clean: 52 | rm -vf $(programs) 53 | 54 | -------------------------------------------------------------------------------- /inst/examples/mpi/cmake/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.4) 2 | 3 | set (SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) 4 | 5 | execute_process(COMMAND R RHOME 6 | OUTPUT_VARIABLE R_HOME) 7 | 8 | find_package(MPI REQUIRED) 9 | set(CMAKE_CXX_COMPILE_FLAGS ${CMAKE_CXX_COMPILE_FLAGS} ${MPI_COMPILE_FLAGS}) 10 | set(CMAKE_CXX_LINK_FLAGS ${CMAKE_CXX_LINK_FLAGS} ${MPI_LINK_FLAGS}) 11 | include_directories(${MPI_INCLUDE_PATH}) 12 | 13 | file(GLOB sources ${SRC_DIR}/*.cpp) 14 | 15 | set(NUM_TRUNC_CHARS 2) 16 | 17 | execute_process(COMMAND R CMD config --cppflags 18 | OUTPUT_VARIABLE RCPPFLAGS) 19 | string(SUBSTRING ${RCPPFLAGS} ${NUM_TRUNC_CHARS} -1 RCPPFLAGS) 20 | include_directories(${RCPPFLAGS}) 21 | 22 | execute_process(COMMAND R CMD config --ldflags 23 | OUTPUT_VARIABLE RLDFLAGS) 24 | string(LENGTH ${RLDFLAGS} RLDFLAGS_LEN) 25 | 26 | if (${RLDFLAGS} MATCHES "[-][L]([^ ;])+") 27 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_L) 28 | string(STRIP ${RLDFLAGS_L} RLDFLAGS_L ) 29 | link_directories(${RLDFLAGS_L} ) 30 | endif() 31 | 32 | if (${RLDFLAGS} MATCHES "[-][l]([^;])+") 33 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_l) 34 | string(STRIP ${RLDFLAGS_l} RLDFLAGS_l ) 35 | endif() 36 | 37 | execute_process(COMMAND Rscript -e "Rcpp:::CxxFlags()" 38 | OUTPUT_VARIABLE RCPPINCL) 39 | string(SUBSTRING ${RCPPINCL} ${NUM_TRUNC_CHARS} -1 RCPPINCL) 40 | include_directories(${RCPPINCL}) 41 | 42 | execute_process(COMMAND Rscript -e "Rcpp:::LdFlags()" 43 | OUTPUT_VARIABLE RCPPLIBS) 44 | if (${RCPPLIBS} MATCHES "[-][L]([^ ;])+") 45 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_L) 46 | link_directories(${RCPPLIBS_L} ) 47 | endif() 48 | 49 | if (${RCPPLIBS} MATCHES "[-][l][R]([^;])+") 50 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_l) 51 | endif() 52 | 53 | execute_process(COMMAND Rscript -e "RInside:::CxxFlags()" 54 | OUTPUT_VARIABLE RINSIDEINCL) 55 | string(SUBSTRING ${RINSIDEINCL} ${NUM_TRUNC_CHARS} -1 RINSIDEINCL) 56 | include_directories(${RINSIDEINCL}) 57 | 58 | execute_process(COMMAND Rscript -e "RInside:::LdFlags()" 59 | OUTPUT_VARIABLE RINSIDELIBS) 60 | if (${RINSIDELIBS} MATCHES "[-][L]([^ ;])+") 61 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_L) 62 | link_directories(${RINSIDELIBS_L}) 63 | endif() 64 | 65 | if (${RINSIDELIBS} MATCHES "[-][l][R]([^;])+") 66 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_l) 67 | endif() 68 | 69 | execute_process(COMMAND R CMD config CXXFLAGS 70 | OUTPUT_VARIABLE RCXXFLAGS) 71 | 72 | execute_process(COMMAND R CMD config BLAS_LIBS 73 | OUTPUT_VARIABLE RBLAS) 74 | 75 | execute_process(COMMAND R CMD config LAPACK_LIBS 76 | OUTPUT_VARIABLE RLAPACK) 77 | 78 | set(CMAKE_CXX_FLAGS "-W -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}") 79 | 80 | if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR 81 | CMAKE_BUILD_TYPE STREQUAL "RelWithDebugInfo" ) 82 | add_definitions("-DDEBUG") 83 | elseif ( CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) 84 | add_definitions("-O3") 85 | endif() 86 | 87 | foreach (next_SOURCE ${sources}) 88 | get_filename_component(source_name ${next_SOURCE} NAME_WE) 89 | add_executable( ${source_name} ${next_SOURCE} ) 90 | 91 | target_link_libraries(${source_name} ${RCPPLIBS_l}) 92 | target_link_libraries(${source_name} ${RINSIDELIBS_l}) 93 | target_link_libraries(${source_name} ${RLDFLAGS_l}) 94 | target_link_libraries(${source_name} ${BLAS_LIBS}) 95 | target_link_libraries(${source_name} ${LAPACK_LIBS}) 96 | target_link_libraries(${source_name} ${MPI_LIBRARIES}) 97 | endforeach (next_SOURCE ${sources}) 98 | 99 | -------------------------------------------------------------------------------- /inst/examples/mpi/rinside_mpi_sample0.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple example showing in R console information about current node 4 | // 5 | // This file was contributed by Jianping Hua 6 | // 7 | // Copyright (C) 2010 - 2011 Jianping Hua, Dirk Eddelbuettel and Romain Francois 8 | // 9 | // GPL'ed 10 | 11 | #include // mpi header 12 | #include // for the embedded R via RInside 13 | 14 | int main(int argc, char *argv[]) { 15 | 16 | // mpi related 17 | int myrank, nodesize; // node information 18 | MPI_Init(&argc,&argv); // mpi initialization 19 | MPI_Comm_rank(MPI_COMM_WORLD, &myrank); // obtain current node rank 20 | MPI_Comm_size(MPI_COMM_WORLD, &nodesize); // obtain total nodes running. 21 | 22 | RInside R(argc, argv); // create an embedded R instance 23 | 24 | std::stringstream txt; 25 | txt << "Hello from node " << myrank // node information 26 | << " of " << nodesize << " nodes!" << std::endl; 27 | 28 | R["txt"] = txt.str(); // assign string var to R variable 'txt' 29 | 30 | R.parseEvalQ("cat(txt)"); // eval init string, ignoring any returns 31 | 32 | MPI_Finalize(); // mpi finalization 33 | 34 | exit(0); 35 | } 36 | -------------------------------------------------------------------------------- /inst/examples/mpi/rinside_mpi_sample1.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple mpi example: simulate sampling/averaging on multiple nodes and gathering the results. 4 | // 5 | // This file was contributed by Jianping Hua 6 | // 7 | // Copyright (C) 2010 - 2011 Jianping Hua, Dirk Eddelbuettel and Romain Francois 8 | // 9 | // GPL'ed 10 | 11 | #include // mpi header file 12 | #include // for the embedded R via RInside 13 | 14 | int main(int argc, char *argv[]) { 15 | 16 | // mpi related 17 | int myrank, nodesize; // node information 18 | int sndcnt = 1, rcvcnt = 1; // # of elements in send/recv buffer 19 | MPI_Init(&argc,&argv); // mpi initialization 20 | MPI_Comm_rank(MPI_COMM_WORLD, &myrank); // obtain current node rank 21 | MPI_Comm_size(MPI_COMM_WORLD, &nodesize); // obtain total nodes running. 22 | double sendValue; // value to be collected in current node 23 | double *allvalues = new double[nodesize]; // to save all results 24 | 25 | // simulation info 26 | // to sample from a uniform distribution 27 | int rangeMin = 0, rangeMax = 10; // range of uniform distribution 28 | int sampleSize = 2; // points in each sample 29 | 30 | try { 31 | RInside R(argc, argv); // create an embedded R instance 32 | 33 | std::stringstream txt; 34 | txt << "x <- " << rangeMin << std::endl; 35 | R.parseEvalQ( txt.str() ); // assign x with lower range of uniform distribution 36 | 37 | txt << "y <- " << rangeMax << std::endl; 38 | R.parseEvalQ( txt.str() ); // assign y with upper range of uniform distribution 39 | 40 | txt << "n <- " << sampleSize << std::endl; 41 | R.parseEvalQ( txt.str() ); // assign n with the size of sample 42 | 43 | std::string evalstr = "mean(runif(n,x,y))"; // sampling, compute the mean 44 | Rcpp::NumericVector m = R.parseEval(evalstr); // eval str, convert result to NumericVector 45 | sendValue = m( 0 ); // assign the return value to the variable to be gathered 46 | 47 | //gather together values from all processes to allvalues 48 | MPI_Gather(&sendValue, sndcnt, MPI_DOUBLE, allvalues, rcvcnt, MPI_DOUBLE, 0, MPI_COMM_WORLD); 49 | 50 | // show what inidividual node's contribution 51 | std::cout << "node " << myrank << " has mean " << m(0) << std::endl; 52 | 53 | } catch(std::exception& ex) { 54 | std::cerr << "Exception caught: " << ex.what() << std::endl; 55 | } catch(...) { 56 | std::cerr << "Unknown exception caught" << std::endl; 57 | } 58 | 59 | // show gathered results in node 0 60 | if ( myrank == 0 ) { 61 | std::cout << "values of all " << nodesize << " trials: " << std::endl; 62 | for ( int i = 0; i < nodesize; i++ ) 63 | std::cout << allvalues[ i ] << ", "; 64 | std::cout << std::endl; 65 | } 66 | 67 | // clean up 68 | delete[] allvalues; 69 | 70 | MPI_Finalize(); // mpi finalization 71 | 72 | exit(0); 73 | } 74 | 75 | -------------------------------------------------------------------------------- /inst/examples/mpi/rinside_mpi_sample2.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple example showing in R console information about current node 4 | // 5 | // MPI C++ API version of file contributed by Jianping Hua 6 | // 7 | // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois 8 | // 9 | // GPL'ed 10 | 11 | #include // mpi header 12 | #include // for the embedded R via RInside 13 | 14 | int main(int argc, char *argv[]) { 15 | 16 | MPI::Init(argc, argv); // mpi initialization 17 | int myrank = MPI::COMM_WORLD.Get_rank(); // obtain current node rank 18 | int nodesize = MPI::COMM_WORLD.Get_size(); // obtain total nodes running. 19 | 20 | RInside R(argc, argv); // create an embedded R instance 21 | 22 | std::stringstream txt; 23 | txt << "Hello from node " << myrank // node information 24 | << " of " << nodesize << " nodes!" << std::endl; 25 | 26 | R["txt"] = txt.str(); // assign string var to R variable 'txt' 27 | 28 | R.parseEvalQ("cat(txt)"); // eval init string, ignoring any returns 29 | 30 | MPI::Finalize(); // mpi finalization 31 | 32 | exit(0); 33 | } 34 | -------------------------------------------------------------------------------- /inst/examples/mpi/rinside_mpi_sample3.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple mpi example: simulate sampling/averaging on multiple nodes and gathering the results. 4 | // 5 | // MPI C++ API version of file contributed by Jianping Hua 6 | // 7 | // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois 8 | // 9 | // GPL'ed 10 | 11 | #include // mpi header file 12 | #include // for the embedded R via RInside 13 | 14 | int main(int argc, char *argv[]) { 15 | 16 | MPI::Init(argc, argv); // mpi initialization 17 | int myrank = MPI::COMM_WORLD.Get_rank(); // obtain current node rank 18 | int nodesize = MPI::COMM_WORLD.Get_size(); // obtain total nodes running. 19 | 20 | int sndcnt = 1, rcvcnt = 1; // # of elements in send/recv buffer 21 | double sendValue; // value to be collected in current node 22 | double *allvalues = new double[nodesize]; // to save all results 23 | 24 | // simulation info 25 | // to sample from a uniform distribution 26 | int rangeMin = 0, rangeMax = 10; // range of uniform distribution 27 | int sampleSize = 2; // points in each sample 28 | 29 | try { 30 | RInside R(argc, argv); // create an embedded R instance 31 | 32 | std::stringstream txt; 33 | txt << "x <- " << rangeMin << std::endl; 34 | R.parseEvalQ( txt.str() ); // assign x with lower range of uniform distribution 35 | 36 | txt << "y <- " << rangeMax << std::endl; 37 | R.parseEvalQ( txt.str() ); // assign y with upper range of uniform distribution 38 | 39 | txt << "n <- " << sampleSize << std::endl; 40 | R.parseEvalQ( txt.str() ); // assign n with the size of sample 41 | 42 | std::string evalstr = "mean(runif(n,x,y))"; // sampling, compute the mean 43 | Rcpp::NumericVector m = R.parseEval(evalstr); // eval str, convert result to NumericVector 44 | sendValue = m( 0 ); // assign the return value to the variable to be gathered 45 | 46 | //gather together values from all processes to allvalues 47 | MPI::COMM_WORLD.Gather((const void*)&sendValue, sndcnt, MPI::DOUBLE, (void*)allvalues, rcvcnt, MPI::DOUBLE, 0); 48 | 49 | // show what inidividual node's contribution 50 | std::cout << "node " << myrank << " has mean " << m(0) << std::endl; 51 | 52 | } catch(std::exception& ex) { 53 | std::cerr << "Exception caught: " << ex.what() << std::endl; 54 | } catch(...) { 55 | std::cerr << "Unknown exception caught" << std::endl; 56 | } 57 | 58 | // show gathered results in node 0 59 | if ( myrank == 0 ) { 60 | std::cout << "values of all " << nodesize << " trials: " << std::endl; 61 | for ( int i = 0; i < nodesize; i++ ) 62 | std::cout << allvalues[ i ] << ", "; 63 | std::cout << std::endl; 64 | } 65 | 66 | // clean up 67 | delete[] allvalues; 68 | 69 | MPI::Finalize(); // mpi finalization 70 | 71 | exit(0); 72 | } 73 | 74 | -------------------------------------------------------------------------------- /inst/examples/mpi/rinside_mpi_sample4.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple mpi example: Usage of RInside with a Master-Slave Model with worker 4 | // 5 | // MPI C API version of file contributed by Nicholas Pezolano and Martin Morgan 6 | // 7 | // Copyright (C) 2010 - 2013 Dirk Eddelbuettel 8 | // Copyright (C) 2013 Nicholas Pezolano 9 | // Copyright (C) 2013 Martin Morgan 10 | // 11 | // GPL'ed 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #define WORKTAG 1 20 | #define DIETAG 2 21 | 22 | /* Local functions */ 23 | static void master(void); 24 | static void slave(RInside &R); 25 | static int get_next_work_item(int &work, const int size_work, std::vector &data); 26 | static void do_work(int work,int &result,RInside &R); 27 | static void initalize(RInside &R); 28 | 29 | int itr = 0; 30 | 31 | int main(int argc, char **argv){ 32 | int myrank; 33 | MPI_Init(&argc, &argv); 34 | MPI_Comm_rank(MPI_COMM_WORLD, &myrank); 35 | RInside R(argc, argv); 36 | 37 | 38 | if (myrank == 0) { 39 | master(); 40 | } else { 41 | initalize(R); 42 | slave(R); 43 | } 44 | 45 | MPI_Finalize(); 46 | return 0; 47 | } 48 | 49 | static void initalize(RInside &R){ 50 | //load the following R library on every R instance 51 | std::string R_libs ="suppressMessages(library(random));"; 52 | R.parseEvalQ(R_libs); 53 | } 54 | 55 | static void master(void){ 56 | int ntasks, rank; 57 | std::vector data; 58 | int work; 59 | int result; 60 | int sum; 61 | MPI_Status status; 62 | 63 | //create some test "data" to pass around 64 | for(int i = 0; i< 10; i++){ 65 | data.push_back(i); 66 | } 67 | 68 | const int size_work = (int)data.size(); 69 | 70 | MPI_Comm_size(MPI_COMM_WORLD, &ntasks); 71 | 72 | for (rank = 1; rank < ntasks; ++rank) { 73 | get_next_work_item(work,size_work,data); 74 | MPI_Send(&work,1,MPI_INT,rank, WORKTAG,MPI_COMM_WORLD); 75 | } 76 | 77 | int ret = get_next_work_item(work,size_work,data); 78 | while (ret == 0) { 79 | MPI_Recv(&result,1,MPI_INT,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&status); 80 | sum += result; 81 | MPI_Send(&work,1,MPI_INT,status.MPI_SOURCE,WORKTAG,MPI_COMM_WORLD); 82 | 83 | ret = get_next_work_item(work,size_work,data); 84 | } 85 | 86 | for (rank = 1; rank < ntasks; ++rank) { 87 | MPI_Recv(&result, 1, MPI_INT, MPI_ANY_SOURCE, 88 | MPI_ANY_TAG, MPI_COMM_WORLD, &status); 89 | sum += result; 90 | } 91 | 92 | for (rank = 1; rank < ntasks; ++rank) { 93 | MPI_Send(0, 0, MPI_INT, rank, DIETAG, MPI_COMM_WORLD); 94 | } 95 | 96 | std::cout << "sum of all iterations = " << sum << std::endl; 97 | } 98 | 99 | static void slave(RInside &R) { 100 | int work; 101 | int result; 102 | MPI_Status status; 103 | 104 | while (1) { 105 | 106 | MPI_Recv(&work, 1, MPI_INT, 0, MPI_ANY_TAG, 107 | MPI_COMM_WORLD, &status); 108 | 109 | if (status.MPI_TAG == DIETAG) { 110 | return; 111 | } 112 | 113 | do_work(work,result,R); 114 | 115 | MPI_Send(&result, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); 116 | } 117 | } 118 | 119 | 120 | static int get_next_work_item(int &work,const int size_work, std::vector &data) { 121 | if (itr >= size_work) { 122 | return -1; 123 | } 124 | 125 | work = data[itr]; 126 | 127 | itr++; 128 | std::cout << "iteration = " << itr << std::endl; 129 | 130 | return 0; 131 | } 132 | 133 | static void do_work(int work,int &result,RInside &R){ 134 | 135 | //create a random number on every slave iteration 136 | R["work"] = work; 137 | std::string Rcmd = "work <- sample(1:10, 1)"; 138 | Rcpp::NumericVector M = R.parseEval(Rcmd); 139 | 140 | result = M(0); 141 | } 142 | -------------------------------------------------------------------------------- /inst/examples/qt/README: -------------------------------------------------------------------------------- 1 | 2 | This directory provides a simple example of using RInside with the Qt 3 | toolkit---using a SVG renderer. Usage is standard Qt usage, through cmake. 4 | 5 | To build from commandline try the following from this directory: 6 | ``` 7 | mkdir build; cd build 8 | cmake -S ../cmake -G "Unix Makefiles" 9 | make -j 10 | ``` 11 | 12 | On Ubuntu you would need at least the following packages installed: libqt6svgwidgets6 qt6-tools-dev-tools qt6-base-dev r-base-dev libqt6svg6-dev 13 | 14 | What could be easier on some systems, depending on how Qt was installed, is using Qt Creator. 15 | This can be done through "Open Project" and loading "CMakeLists.txt". 16 | 17 | If you are on macOs and there are errors on "SUBSTRING" needing 4 arguments try starting QtCreator manually from a terminal. 18 | If you get similar errors on Windows then perhaps R isn't on the PATH and you might need to add the `bin/x64` folder of R manually. 19 | 20 | To generate SVG output, this version depends on the cairoDevice package for R 21 | which you may need to install. According to its author Michael Lawrence, 22 | there are two small issues. The first is that the SVG produced by 23 | cairoDevice is a littler richer than the subset which Qt can show. We 24 | address this by filtering the file before viewing it. The other is an 25 | apparent error in the clipping which we cannot do anything about---Michael 26 | considers it a rendering issue. 27 | 28 | All the help by Michael in getting the svg variant to roll is gratefully 29 | acknowledged. 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /inst/examples/qt/cmake/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.21) 2 | 3 | project(qtdensitydemo) 4 | find_package(Qt6 REQUIRED) 5 | find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets SvgWidgets) 6 | 7 | set(CMAKE_VERBOSE_MAKEFILE ON) 8 | set(CMAKE_MESSAGE_CONTEXT_SHOW ON) 9 | 10 | set(CMAKE_CXX_STANDARD 20) 11 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 12 | 13 | set(CMAKE_FIND_FRAMEWORK ON) 14 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 15 | 16 | set(CMAKE_VERBOSE_MAKEFILE 0) 17 | 18 | set(CMAKE_AUTOMOC ON) 19 | set(CMAKE_AUTORCC ON) 20 | set(CMAKE_AUTOUIC ON) 21 | 22 | set(QT_USE_QTSVG 1) 23 | 24 | add_definitions(${QT_DEFINITIONS}) 25 | add_definitions(-DQT_DLL) 26 | include_directories(${QT_INCLUDE_DIR}) 27 | link_directories(${QT_LIBRARY_DIR}) 28 | 29 | execute_process(COMMAND R RHOME 30 | OUTPUT_VARIABLE R_HOME) 31 | 32 | set(sources ../main.cpp 33 | ../qtdensity.cpp) 34 | 35 | set(headers ../qtdensity.h) 36 | 37 | set(NUM_TRUNC_CHARS 2) 38 | 39 | execute_process(COMMAND R CMD config --cppflags OUTPUT_VARIABLE RCPPFLAGS) 40 | string(SUBSTRING ${RCPPFLAGS} ${NUM_TRUNC_CHARS} -1 RCPPFLAGS) 41 | include_directories(${RCPPFLAGS}) 42 | 43 | execute_process(COMMAND R CMD config --ldflags OUTPUT_VARIABLE RLDFLAGS) 44 | string(LENGTH ${RLDFLAGS} RLDFLAGS_LEN) 45 | string(STRIP ${RLDFLAGS} RLDFLAGS) 46 | 47 | execute_process(COMMAND Rscript -e "Rcpp:::CxxFlags()" OUTPUT_VARIABLE RCPPINCL) 48 | string(SUBSTRING ${RCPPINCL} ${NUM_TRUNC_CHARS} -1 RCPPINCL) 49 | string(REPLACE "\"" "" RCPPINCL ${RCPPINCL}) #Rcpp::CxxFlags() adds quotes around the include directory, which is friendly and all but breaks include_directories 50 | include_directories(${RCPPINCL}) 51 | 52 | execute_process(COMMAND Rscript -e "Rcpp:::LdFlags()" OUTPUT_VARIABLE RCPPLIBS) 53 | if (${RCPPLIBS} MATCHES "[-][L]([^ ;])+") 54 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_L) 55 | link_directories(${RCPPLIBS_L} ) 56 | endif() 57 | 58 | if (${RCPPLIBS} MATCHES "[-][l][R]([^;])+") 59 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_l) 60 | endif() 61 | 62 | execute_process(COMMAND Rscript -e "RInside:::CxxFlags()" 63 | OUTPUT_VARIABLE RINSIDEINCL) 64 | string(SUBSTRING ${RINSIDEINCL} ${NUM_TRUNC_CHARS} -1 RINSIDEINCL) 65 | include_directories(${RINSIDEINCL}) 66 | 67 | execute_process(COMMAND Rscript -e "RInside:::LdFlags()" OUTPUT_VARIABLE RINSIDELIBS) 68 | string(STRIP ${RINSIDELIBS} RINSIDELIBS ) 69 | string(REPLACE "\"" "" RINSIDELIBS ${RINSIDELIBS}) 70 | 71 | if (${RINSIDELIBS} MATCHES "[-][L]([^ ;])+") 72 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_L) 73 | link_directories(${RINSIDELIBS_L}) 74 | endif() 75 | 76 | if (${RINSIDELIBS} MATCHES "[-][l][R]([^;])+") 77 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_l) 78 | endif() 79 | 80 | if (${RINSIDELIBS} MATCHES ".+\.a$") 81 | set(RINSIDELIBS_l ${RINSIDELIBS}) 82 | endif() 83 | 84 | execute_process(COMMAND R CMD config CXXFLAGS OUTPUT_VARIABLE RCXXFLAGS) 85 | execute_process(COMMAND R CMD config BLAS_LIBS OUTPUT_VARIABLE RBLAS) 86 | execute_process(COMMAND R CMD config LAPACK_LIBS OUTPUT_VARIABLE RLAPACK) 87 | 88 | set(CMAKE_CXX_FLAGS "-W -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}") 89 | 90 | if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR 91 | CMAKE_BUILD_TYPE STREQUAL "RelWithDebugInfo" ) 92 | add_definitions("-DDEBUG") 93 | elseif ( CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) 94 | add_definitions("-O3") 95 | endif() 96 | 97 | qt_add_executable(qtdensitydemo ${sources} ${headers}) 98 | 99 | target_link_libraries( 100 | qtdensitydemo 101 | PRIVATE 102 | Qt6::Gui 103 | Qt6::Core 104 | Qt6::Widgets 105 | Qt6::SvgWidgets 106 | ${BLAS_LIBS} 107 | ${LAPACK_LIBS} 108 | ${RCPPLIBS_l} 109 | ${RINSIDELIBS_l} 110 | ${RLDFLAGS} 111 | ) 112 | -------------------------------------------------------------------------------- /inst/examples/qt/main.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Qt usage example for RInside, inspired by the standard 'density 4 | // sliders' example for other GUI toolkits 5 | // 6 | // Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois 7 | 8 | 9 | #include 10 | #include "qtdensity.h" 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | RInside R(argc, argv); // create an embedded R instance 15 | 16 | QApplication app(argc, argv); 17 | QtDensity qtdensity(R); // pass R inst. by reference 18 | return app.exec(); 19 | } 20 | -------------------------------------------------------------------------------- /inst/examples/qt/qtdensity.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // Qt usage example for RInside, inspired by the standard 'density 4 | // sliders' example for other GUI toolkits -- this time with SVG 5 | // 6 | // Copyright (C) 2011 - 2013 Dirk Eddelbuettel and Romain Francois 7 | 8 | #include "qtdensity.h" 9 | #include 10 | 11 | QtDensity::QtDensity(RInside & R) : m_R(R) 12 | { 13 | m_bw = 100; // initial bandwidth, will be scaled by 100 so 1.0 14 | m_kernel = 0; // initial kernel: gaussian 15 | m_cmd = "c(rnorm(100,0,1), rnorm(50,5,1))"; // simple mixture 16 | m_R["bw"] = m_bw; // pass bandwidth to R, and have R compute a temp.file name 17 | m_tempfile = QString::fromStdString(Rcpp::as(m_R.parseEval("tfile <- tempfile()"))); 18 | m_svgfile = QString::fromStdString(Rcpp::as(m_R.parseEval("sfile <- tempfile()"))); 19 | setupDisplay(); 20 | } 21 | 22 | void QtDensity::setupDisplay(void) { 23 | QWidget *window = new QWidget; 24 | window->setWindowTitle("Qt and RInside demo: density estimation"); 25 | 26 | QSpinBox *spinBox = new QSpinBox; 27 | QSlider *slider = new QSlider(Qt::Horizontal); 28 | spinBox->setRange(5, 200); 29 | slider->setRange(5, 200); 30 | QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int))); 31 | QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int))); 32 | spinBox->setValue(m_bw); 33 | QObject::connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(getBandwidth(int))); 34 | 35 | QLabel *cmdLabel = new QLabel("R command for random data creation"); 36 | QLineEdit *cmdEntry = new QLineEdit(m_cmd); 37 | QObject::connect(cmdEntry, SIGNAL(textEdited(QString)), this, SLOT(getRandomDataCmd(QString))); 38 | QObject::connect(cmdEntry, SIGNAL(editingFinished()), this, SLOT(runRandomDataCmd())); 39 | 40 | QGroupBox *kernelRadioBox = new QGroupBox("Density Estimation kernel"); 41 | QRadioButton *radio1 = new QRadioButton("&Gaussian"); 42 | QRadioButton *radio2 = new QRadioButton("&Epanechnikov"); 43 | QRadioButton *radio3 = new QRadioButton("&Rectangular"); 44 | QRadioButton *radio4 = new QRadioButton("&Triangular"); 45 | QRadioButton *radio5 = new QRadioButton("&Cosine"); 46 | radio1->setChecked(true); 47 | QVBoxLayout *vbox = new QVBoxLayout; 48 | vbox->addWidget(radio1); 49 | vbox->addWidget(radio2); 50 | vbox->addWidget(radio3); 51 | vbox->addWidget(radio4); 52 | vbox->addWidget(radio5); 53 | kernelRadioBox->setMinimumSize(260,140); 54 | kernelRadioBox->setMaximumSize(260,140); 55 | kernelRadioBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 56 | kernelRadioBox->setLayout(vbox); 57 | 58 | QButtonGroup *kernelGroup = new QButtonGroup; 59 | kernelGroup->addButton(radio1, 0); 60 | kernelGroup->addButton(radio2, 1); 61 | kernelGroup->addButton(radio3, 2); 62 | kernelGroup->addButton(radio4, 3); 63 | kernelGroup->addButton(radio5, 4); 64 | QObject::connect(kernelGroup, SIGNAL(idClicked(int)), this, SLOT(getKernel(int))); 65 | 66 | m_svg = new QSvgWidget(); 67 | runRandomDataCmd(); // also calls plot() 68 | 69 | QGroupBox *estimationBox = new QGroupBox("Density estimation bandwidth (scaled by 100)"); 70 | QHBoxLayout *spinners = new QHBoxLayout; 71 | spinners->addWidget(spinBox); 72 | spinners->addWidget(slider); 73 | QVBoxLayout *topright = new QVBoxLayout; 74 | topright->addLayout(spinners); 75 | topright->addWidget(cmdLabel); 76 | topright->addWidget(cmdEntry); 77 | estimationBox->setMinimumSize(360,140); 78 | estimationBox->setMaximumSize(360,140); 79 | estimationBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 80 | estimationBox->setLayout(topright); 81 | QHBoxLayout *upperlayout = new QHBoxLayout; 82 | upperlayout->addWidget(kernelRadioBox); 83 | upperlayout->addWidget(estimationBox); 84 | 85 | QHBoxLayout *lowerlayout = new QHBoxLayout; 86 | lowerlayout->addWidget(m_svg); 87 | 88 | QVBoxLayout *outer = new QVBoxLayout; 89 | outer->addLayout(upperlayout); 90 | outer->addLayout(lowerlayout); 91 | window->setLayout(outer); 92 | window->show(); 93 | } 94 | 95 | void QtDensity::plot(void) { 96 | const char *kernelstrings[] = { "gaussian", "epanechnikov", "rectangular", "triangular", "cosine" }; 97 | m_R["bw"] = m_bw; 98 | m_R["kernel"] = kernelstrings[m_kernel]; // that passes the string to R 99 | std::string cmd0 = "svg(width=6,height=6,pointsize=10,filename=tfile); "; 100 | std::string cmd1 = "plot(density(y, bw=bw/100, kernel=kernel), xlim=range(y)+c(-2,2), main=\"Kernel: "; 101 | std::string cmd2 = "\"); points(y, rep(0, length(y)), pch=16, col=rgb(0,0,0,1/4)); dev.off()"; 102 | std::string cmd = cmd0 + cmd1 + kernelstrings[m_kernel] + cmd2; // stick the selected kernel in the middle 103 | m_R.parseEvalQ(cmd); 104 | filterFile(); // we need to simplify the svg file for display by Qt 105 | m_svg->load(m_svgfile); 106 | } 107 | 108 | void QtDensity::getBandwidth(int bw) { 109 | if (bw != m_bw) { 110 | m_bw = bw; 111 | plot(); 112 | } 113 | } 114 | 115 | void QtDensity::getKernel(int kernel) { 116 | if (kernel != m_kernel) { 117 | m_kernel = kernel; 118 | plot(); 119 | } 120 | } 121 | 122 | void QtDensity::getRandomDataCmd(QString txt) { 123 | m_cmd = txt; 124 | } 125 | 126 | void QtDensity::runRandomDataCmd(void) { 127 | std::string cmd = "y2 <- " + m_cmd.toStdString() + "; y <- y2"; 128 | m_R.parseEvalQNT(cmd); 129 | plot(); // after each random draw, update plot with estimate 130 | } 131 | 132 | void QtDensity::filterFile() { 133 | // cairoDevice creates richer SVG than Qt can display 134 | // but per Michaele Lawrence, a simple trick is to s/symbol/g/ which we do here 135 | QFile infile(m_tempfile); 136 | infile.open(QFile::ReadOnly); 137 | QFile outfile(m_svgfile); 138 | outfile.open(QFile::WriteOnly | QFile::Truncate); 139 | 140 | QTextStream in(&infile); 141 | QTextStream out(&outfile); 142 | static QRegularExpression rx1(" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | class QtDensity : public QMainWindow 29 | { 30 | Q_OBJECT 31 | 32 | public: 33 | QtDensity(RInside & R); 34 | 35 | private slots: 36 | void getBandwidth(int bw); 37 | void getKernel(int kernel); 38 | void getRandomDataCmd(QString txt); 39 | void runRandomDataCmd(void); 40 | 41 | private: 42 | void setupDisplay(void); // standard GUI boilderplate of arranging things 43 | void plot(void); // run a density plot in R and update the 44 | void filterFile(void); // modify the richer SVG produced by R 45 | 46 | QSvgWidget *m_svg; // the SVG device 47 | RInside & m_R; // reference to the R instance passed to constructor 48 | QString m_tempfile; // name of file used by R for plots 49 | QString m_svgfile; // another temp file, this time from Qt 50 | int m_bw, m_kernel; // parameters used to estimate the density 51 | QString m_cmd; // random draw command string 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /inst/examples/qt/qtdensity.pro: -------------------------------------------------------------------------------- 1 | ## -*- mode: Makefile; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | ## 3 | ## Qt usage example for RInside, inspired by the standard 'density 4 | ## sliders' example for other GUI toolkits 5 | ## 6 | ## This file can be used across operating systems as qmake selects appropriate 7 | ## values as needed, as do the R and R-related calls below. See the thread at 8 | ## http://thread.gmane.org/gmane.comp.lang.r.rcpp/4376/focus=4402 9 | ## for discussion specific to Windows. 10 | ## 11 | ## Copyright (C) 2012 Dirk Eddelbuettel and Romain Francois 12 | 13 | ## build an app based on the one headers and two source files 14 | TEMPLATE = app 15 | HEADERS = qtdensity.h 16 | SOURCES = qtdensity.cpp main.cpp 17 | 18 | ## beyond the default configuration, also use SVG graphics 19 | QT += svg 20 | 21 | ## comment this out if you need a different version of R, 22 | ## and set set R_HOME accordingly as an environment variable 23 | R_HOME = $$system(R RHOME) 24 | #message("R_HOME is" $$R_HOME) 25 | 26 | ## include headers and libraries for R 27 | RCPPFLAGS = $$system($$R_HOME/bin/R CMD config --cppflags) 28 | RLDFLAGS = $$system($$R_HOME/bin/R CMD config --ldflags) 29 | RBLAS = $$system($$R_HOME/bin/R CMD config BLAS_LIBS) 30 | RLAPACK = $$system($$R_HOME/bin/R CMD config LAPACK_LIBS) 31 | 32 | ## if you need to set an rpath to R itself, also uncomment 33 | RRPATH = -Wl,-rpath,$$R_HOME/lib 34 | 35 | ## include headers and libraries for Rcpp interface classes 36 | ## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted 37 | RCPPINCL = $$system($$R_HOME/bin/Rscript -e \"Rcpp:::CxxFlags\(\)\") 38 | RCPPLIBS = $$system($$R_HOME/bin/Rscript -e \"Rcpp:::LdFlags\(\)\") 39 | 40 | ## for some reason when building with Qt we get this each time 41 | ## /usr/local/lib/R/site-library/Rcpp/include/Rcpp/module/Module_generated_ctor_signature.h:25: warning: unused parameter ‘classname 42 | ## so we turn unused parameter warnings off 43 | ## no longer needed with Rcpp 0.9.3 or later 44 | #RCPPWARNING = -Wno-unused-parameter 45 | 46 | ## include headers and libraries for RInside embedding classes 47 | RINSIDEINCL = $$system($$R_HOME/bin/Rscript -e \"RInside:::CxxFlags\(\)\") 48 | RINSIDELIBS = $$system($$R_HOME/bin/Rscript -e \"RInside:::LdFlags\(\)\") 49 | 50 | ## compiler etc settings used in default make rules 51 | QMAKE_CXXFLAGS += $$RCPPWARNING $$RCPPFLAGS $$RCPPINCL $$RINSIDEINCL 52 | QMAKE_LIBS += $$RLDFLAGS $$RBLAS $$RLAPACK $$RINSIDELIBS $$RCPPLIBS 53 | 54 | ## addition clean targets 55 | QMAKE_CLEAN += qtdensity Makefile 56 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/GNUmakefile: -------------------------------------------------------------------------------- 1 | ## -*- mode: make; tab-width: 8; -*- 2 | ## 3 | ## Simple Makefile 4 | ## 5 | ## TODO: 6 | ## proper configure for non-Debian file locations, [ Done ] 7 | ## allow RHOME to be set for non-default R etc 8 | 9 | ## comment this out if you need a different version of R, 10 | ## and set set R_HOME accordingly as an environment variable 11 | R_HOME := $(shell R RHOME) 12 | 13 | sources_datatypes := $(wildcard datatypes/*.cpp) 14 | objects_datatypes := $(sources_datatypes:.cpp=.o) 15 | sources_server := $(wildcard server/*.cpp) 16 | objects_server := $(sources_server:.cpp=.o) 17 | sources_client := $(wildcard client/*.cpp) 18 | objects_client := $(sources_client:.cpp=.o) 19 | sources_common := $(wildcard common/*.cpp) 20 | objects_common := $(sources_common:.cpp=.o) 21 | server := example_server 22 | client := example_client 23 | 24 | ## include headers and libraries for R 25 | RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) 26 | RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) 27 | RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) 28 | RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) 29 | 30 | ## if you need to set an rpath to R itself, also uncomment 31 | #RRPATH := -Wl,-rpath,$(R_HOME)/lib 32 | 33 | ## include headers and libraries for Rcpp interface classes 34 | ## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted 35 | RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 36 | RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 37 | 38 | 39 | ## include headers and libraries for RInside embedding classes 40 | RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 41 | RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 42 | 43 | ## compiler etc settings used in default make rules 44 | CXX := $(shell $(R_HOME)/bin/R CMD config CXX) 45 | CPPFLAGS := -std=c++11 -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) 46 | CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) 47 | LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) 48 | 49 | all: $(server) $(client) 50 | echo "\n\nCompilation finished.\nRun ./example_server in one shell, then run ./example_client in another." 51 | 52 | $(server): $(objects_server) $(objects_common) $(objects_datatypes) example_server.o 53 | $(CXX) $+ $(LDLIBS) -o $@ 54 | 55 | $(client): $(objects_client) $(objects_common) $(objects_datatypes) example_client.o 56 | $(CXX) $+ $(LDLIBS) -o $@ 57 | 58 | %.o: %.cpp 59 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -I. -c $+ -o $@ 60 | 61 | clean: 62 | rm -vf $(server) $(client) $(objects_server) $(objects_client) $(objects_common) $(objects_datatypes) example_server.o example_client.o 63 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Sandboxed Server 3 | 4 | The example provided in this directory requires `RInside` to be built with 5 | callback support. This can be enabled by uncommenting one line in the file 6 | `RInsideConfig.h` to define the preprocessor constant `RINSIDE_CALLBACKS`, 7 | and then rebuilding. 8 | 9 | Alternatively, adding a compiler flag `-DRINSIDE_CALLBACKS` and reinstalling 10 | would do too; this also requires using the same flag when building the 11 | example or similar applications. 12 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/client/callback_helper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Christian Authmann 3 | */ 4 | 5 | 6 | namespace callback_helper { 7 | // A recursive template sending the TYPEIDs of all template parameters over the stream 8 | template 9 | struct send_pack; 10 | 11 | template 12 | struct send_pack { 13 | static void send(BinaryStream &stream) { 14 | auto type = TYPEID(); 15 | stream.write(type); 16 | send_pack::send(stream); 17 | } 18 | }; 19 | 20 | template <> 21 | struct send_pack<> { 22 | static void send(BinaryStream &stream) { 23 | } 24 | }; 25 | 26 | // An exception when the wrong type is sent over the stream 27 | class type_mismatch_exception : std::exception { 28 | }; 29 | 30 | // An exception when the server failed to transform a parameter, but can still continue 31 | class parameter_error_exception : public std::runtime_error { 32 | public: 33 | explicit parameter_error_exception(const std::string &error) : std::runtime_error(error) {}; 34 | }; 35 | 36 | // read a typeid from the stream, compare it to the expected type, then read the value 37 | template 38 | T read_from_stream_with_typeid(BinaryStream &stream) { 39 | auto result = stream.read(); 40 | if (result == RIS_REPLY_ERROR) { 41 | auto error = stream.read(); 42 | throw parameter_error_exception(error); 43 | } 44 | else if (result != RIS_REPLY_VALUE) { 45 | throw std::runtime_error("Invalid reply from server"); 46 | } 47 | auto type = stream.read(); 48 | if (type != TYPEID()) { 49 | printf("trying to read type %d, got type %d\n", (int) TYPEID(), (int) type); 50 | throw type_mismatch_exception(); 51 | } 52 | return stream.read(); 53 | } 54 | 55 | // auto-generated functions for calling callbacks 56 | template 57 | void call(const std::function &fun, BinaryStream &stream) { 58 | RESULT_TYPE result = fun(); 59 | int32_t result_type = TYPEID(); 60 | stream.write(result_type); 61 | stream.write(result); 62 | } 63 | template 64 | void call(const std::function &fun, BinaryStream &stream) { 65 | auto x0 = read_from_stream_with_typeid::type>(stream); 66 | 67 | RESULT_TYPE result = fun(x0); 68 | int32_t result_type = TYPEID(); 69 | stream.write(result_type); 70 | stream.write(result); 71 | } 72 | template 73 | void call(const std::function &fun, BinaryStream &stream) { 74 | auto x0 = read_from_stream_with_typeid::type>(stream); 75 | auto x1 = read_from_stream_with_typeid::type>(stream); 76 | 77 | RESULT_TYPE result = fun(x0, x1); 78 | int32_t result_type = TYPEID(); 79 | stream.write(result_type); 80 | stream.write(result); 81 | } 82 | template 83 | void call(const std::function &fun, BinaryStream &stream) { 84 | auto x0 = read_from_stream_with_typeid::type>(stream); 85 | auto x1 = read_from_stream_with_typeid::type>(stream); 86 | auto x2 = read_from_stream_with_typeid::type>(stream); 87 | 88 | RESULT_TYPE result = fun(x0, x1, x2); 89 | int32_t result_type = TYPEID(); 90 | stream.write(result_type); 91 | stream.write(result); 92 | } 93 | // TODO: more parameters 94 | } 95 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/client/rinsideclient.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Christian Authmann 3 | */ 4 | 5 | 6 | #include "rinsideclient.h" 7 | #include "common/constants.h" 8 | #include 9 | #include 10 | 11 | 12 | RInsideClient::RInsideClient(BinaryStream &_stream) : stream(std::move(_stream)), next_callback_id(1), had_unrecoverable_error(false), can_send_command(false) { 13 | stream.write(RIS_MAGIC_NUMBER); 14 | can_send_command = true; 15 | } 16 | 17 | RInsideClient::~RInsideClient() { 18 | if (!had_unrecoverable_error && can_send_command) { 19 | try { 20 | stream.write(RIS_CMD_EXIT); 21 | } 22 | catch (...) { 23 | // don't ever throw in a destructor! 24 | } 25 | } 26 | } 27 | 28 | 29 | void RInsideClient::runScript(const std::string code, int32_t result_typeid) { 30 | writeCommand(RIS_CMD_RUN); 31 | stream.write(code); 32 | stream.write(result_typeid); 33 | 34 | while (true) { 35 | auto reply = stream.read(); 36 | if (reply == RIS_REPLY_CALLBACK) { 37 | auto callback_id = stream.read(); 38 | 39 | auto &func = callbacks.at(callback_id); 40 | try { 41 | func(); 42 | } 43 | catch (const callback_helper::parameter_error_exception &e) { 44 | // This is a recoverable error! 45 | can_send_command = true; 46 | throw std::runtime_error(e.what()); 47 | } 48 | catch (...) { 49 | had_unrecoverable_error = true; 50 | throw; 51 | } 52 | } 53 | else if (reply == RIS_REPLY_OK) { 54 | if (result_typeid != 0) 55 | unrecoverable_error("runScript() did not return a value when one was requested"); 56 | return; 57 | } 58 | else if (reply == RIS_REPLY_VALUE) { 59 | if (result_typeid == 0) 60 | unrecoverable_error("runScript() did return a value when none was requested"); 61 | 62 | auto type = stream.read(); 63 | if (type != result_typeid) 64 | unrecoverable_error("runScript() did return a value of the wrong type"); 65 | return; 66 | } 67 | } 68 | } 69 | 70 | std::string RInsideClient::getConsoleOutput() { 71 | writeCommand(RIS_CMD_GETCONSOLE); 72 | readReply(false, true); 73 | auto result = stream.read(); 74 | can_send_command = true; 75 | return result; 76 | } 77 | 78 | 79 | void RInsideClient::initPlot(uint32_t width, uint32_t height) { 80 | writeCommand(RIS_CMD_INITPLOT); 81 | stream.write(width); 82 | stream.write(height); 83 | readReply(true, false); 84 | can_send_command = true; 85 | } 86 | 87 | std::string RInsideClient::getPlot() { 88 | writeCommand(RIS_CMD_GETPLOT); 89 | readReply(false, true); 90 | auto result = stream.read(); 91 | can_send_command = true; 92 | return result; 93 | } 94 | 95 | void RInsideClient::writeCommand(char command) { 96 | if (had_unrecoverable_error) 97 | throw std::runtime_error("RInsideClient cannot continue due to previous unrecoverable errors"); 98 | if (!can_send_command) 99 | throw std::runtime_error("RInsideClient cannot send a command at this time"); 100 | 101 | stream.write(command); 102 | can_send_command = false; 103 | } 104 | 105 | char RInsideClient::readReply(bool accept_ok, bool accept_value) { 106 | auto reply = stream.read(); 107 | if (reply == RIS_REPLY_ERROR) { 108 | auto error = stream.read(); 109 | can_send_command = true; 110 | throw std::runtime_error(std::string("Error in R Server: ") + error); 111 | } 112 | if (reply == RIS_REPLY_OK && !accept_ok) 113 | unrecoverable_error("Got unexpected reply from the R server"); 114 | if (reply == RIS_REPLY_VALUE && !accept_value) 115 | unrecoverable_error("Got unexpected reply from the R server"); 116 | 117 | return reply; 118 | } 119 | 120 | void RInsideClient::unrecoverable_error(const std::string &error) { 121 | had_unrecoverable_error = true; 122 | throw std::runtime_error(error); 123 | } 124 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/client/rinsideclient.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Christian Authmann 3 | */ 4 | 5 | #pragma once 6 | 7 | #include "common/binarystream.h" 8 | #include "common/constants.h" 9 | #include "common/typeid.h" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | #include "callback_helper.h" 18 | 19 | class RInsideClient { 20 | public: 21 | 22 | RInsideClient(BinaryStream &stream); 23 | ~RInsideClient(); 24 | 25 | void parseEvalQ(const std::string &code) { 26 | runScript(code, 0); 27 | can_send_command = true; 28 | }; 29 | 30 | template T parseEval(const std::string &code) { 31 | runScript(code, TYPEID()); 32 | auto result = stream.read(); 33 | can_send_command = true; 34 | return result; 35 | }; 36 | 37 | template 38 | void setValue(const std::string &name, const T &value) { 39 | writeCommand(RIS_CMD_SETVALUE); 40 | stream.write(name); 41 | stream.write(TYPEID()); 42 | stream.write(value); 43 | 44 | readReply(true, false); 45 | can_send_command = true; 46 | }; 47 | 48 | template 49 | T getValue(const std::string &name) { 50 | writeCommand(RIS_CMD_GETVALUE); 51 | stream.write(name); 52 | stream.write(TYPEID()); 53 | 54 | readReply(false, true); 55 | 56 | auto type = stream.read(); 57 | if (type != TYPEID()) 58 | unrecoverable_error("getValue() returned wrong type"); 59 | auto result = stream.read(); 60 | can_send_command = true; 61 | return result; 62 | }; 63 | 64 | template 65 | void setCallback(const std::string &name, std::function &callback) { 66 | uint32_t callback_id = next_callback_id++; 67 | int32_t result_type = TYPEID(); 68 | size_t paramcount = sizeof...(Params); 69 | 70 | writeCommand(RIS_CMD_SETCALLBACK); 71 | stream.write(name); 72 | stream.write(callback_id); 73 | stream.write(result_type); 74 | stream.write(paramcount); 75 | // now write the types of the parameters 76 | callback_helper::send_pack::send(stream); 77 | 78 | // remember the callback 79 | std::function func = std::bind(callback_helper::call, std::ref(callback), std::ref(stream)); 80 | callbacks[callback_id] = func; 81 | readReply(true, false); 82 | can_send_command = true; 83 | } 84 | 85 | std::string getConsoleOutput(); 86 | 87 | void initPlot(uint32_t width=800, uint32_t height=600); 88 | std::string getPlot(); 89 | private: 90 | void runScript(const std::string code, int32_t result_typeid); 91 | void writeCommand(char command); 92 | char readReply(bool accept_ok = true, bool accept_value = false); 93 | 94 | void unrecoverable_error(const std::string &error); 95 | 96 | BinaryStream stream; 97 | uint32_t next_callback_id; 98 | std::map > callbacks; 99 | bool had_unrecoverable_error; 100 | bool can_send_command; 101 | }; 102 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/common/binarystream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Christian Authmann 3 | */ 4 | 5 | #include "binarystream.h" 6 | 7 | #include 8 | #include // memset(), strerror() 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | BinaryStream::BinaryStream(int read_fd, int write_fd) : is_eof(false), read_fd(read_fd), write_fd(write_fd) { 19 | } 20 | 21 | BinaryStream::~BinaryStream() { 22 | close(); 23 | } 24 | 25 | void BinaryStream::close() { 26 | if (read_fd == write_fd) 27 | write_fd = -1; 28 | if (read_fd >= 0) { 29 | ::close(read_fd); 30 | read_fd = -1; 31 | } 32 | if (write_fd >= 0) { 33 | ::close(write_fd); 34 | write_fd = -1; 35 | } 36 | is_eof = true; 37 | } 38 | 39 | BinaryStream::BinaryStream(BinaryStream &&other) : is_eof(other.is_eof), read_fd(other.read_fd), write_fd(other.write_fd) { 40 | other.is_eof = true; 41 | other.read_fd = -1; 42 | other.write_fd = -1; 43 | } 44 | 45 | BinaryStream &BinaryStream::operator=(BinaryStream &&other) { 46 | std::swap(is_eof, other.is_eof); 47 | std::swap(read_fd, other.read_fd); 48 | std::swap(write_fd, other.write_fd); 49 | return *this; 50 | } 51 | 52 | 53 | BinaryStream BinaryStream::connectToUnixSocket(const char *server_path) { 54 | int new_fd = socket(AF_UNIX, SOCK_STREAM, 0); 55 | if (new_fd < 0) 56 | throw stream_exception(); 57 | 58 | struct sockaddr_un server_addr; 59 | memset((void *) &server_addr, 0, sizeof(server_addr)); 60 | 61 | server_addr.sun_family = AF_UNIX; 62 | strcpy(server_addr.sun_path, server_path); 63 | if (connect(new_fd, (sockaddr *) &server_addr, sizeof(server_addr)) == -1) { 64 | ::close(new_fd); 65 | throw stream_exception(); 66 | } 67 | 68 | return BinaryStream(new_fd, new_fd); 69 | } 70 | 71 | 72 | void BinaryStream::write(const char *buffer, size_t len) { 73 | if (write_fd < 0) 74 | throw stream_exception(); 75 | 76 | //printf("Stream: writing %lu bytes\n", len); 77 | auto res = ::write(write_fd, buffer, len); 78 | if (res < 0 || (size_t) res != len) { 79 | // strerror(errno); 80 | throw stream_exception(); 81 | } 82 | } 83 | 84 | size_t BinaryStream::read(char *buffer, size_t len) { 85 | if (read_fd < 0 || is_eof) 86 | throw stream_exception(); 87 | 88 | //printf("Stream: reading %lu bytes\n", len); 89 | 90 | size_t remaining = len; 91 | size_t bytes_read = 0; 92 | while (remaining > 0) { 93 | auto r = ::read(read_fd, buffer, remaining); 94 | if (r == 0) { 95 | is_eof = true; 96 | throw stream_exception(); 97 | } 98 | if (r < 0) { 99 | // strerror(errno); 100 | throw stream_exception(); 101 | } 102 | bytes_read += r; 103 | buffer += r; 104 | remaining -= r; 105 | } 106 | if (bytes_read != len) 107 | throw stream_exception(); 108 | 109 | return bytes_read; 110 | } 111 | 112 | 113 | 114 | namespace serialization { 115 | // Strings 116 | void serializer::serialize(BinaryStream &stream, const std::string &string) { 117 | size_t len = string.size(); 118 | if (len > (size_t) (1<<31)) 119 | throw BinaryStream::stream_exception(); 120 | stream.write(len); 121 | stream.write(string.data(), len); 122 | } 123 | 124 | std::string serializer::deserialize(BinaryStream &stream) { 125 | auto len = stream.read(); 126 | if (len == 0) 127 | return ""; 128 | 129 | if (len > (size_t) (1<<31)) 130 | throw BinaryStream::stream_exception(); 131 | 132 | std::unique_ptr buffer( new char[len] ); 133 | stream.read(buffer.get(), len); 134 | 135 | std::string string(buffer.get(), len); 136 | return string; 137 | } 138 | 139 | // Vectors 140 | template 141 | void serializer>::serialize(BinaryStream &stream, const std::vector &vec) { 142 | size_t size = vec.size(); 143 | if (size > (size_t) (1<<31)) 144 | throw BinaryStream::stream_exception(); 145 | stream.write(size); 146 | for (size_t i=0;i 150 | std::vector serializer>::deserialize(BinaryStream &stream) { 151 | std::vector vec; 152 | auto size = stream.read(); 153 | if (size > (size_t) (1<<31)) 154 | throw BinaryStream::stream_exception(); 155 | vec.reserve(size); 156 | for (size_t i=0;i()); 158 | return vec; 159 | }; 160 | 161 | // Note: when adding more serializers, don't forget to add their declaration in binarystream.h! 162 | 163 | // Make sure to instantiate the vectors we need 164 | template struct serializer>; 165 | template struct serializer>; 166 | template struct serializer>; 167 | template struct serializer>; 168 | template struct serializer>; 169 | template struct serializer>; 170 | template struct serializer>; 171 | template struct serializer>; 172 | template struct serializer>; 173 | template struct serializer>; 174 | template struct serializer>; 175 | } 176 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/common/constants.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Christian Authmann 3 | */ 4 | 5 | #pragma once 6 | 7 | 8 | #define ris_socket_address "example_server.sock" 9 | 10 | const uint32_t RIS_MAGIC_NUMBER = 0xF00BA5; 11 | const char RIS_CMD_SETVALUE = 1; 12 | const char RIS_CMD_GETVALUE = 2; 13 | const char RIS_CMD_SETCALLBACK = 3; 14 | const char RIS_CMD_RUN = 4; 15 | const char RIS_CMD_GETCONSOLE = 5; 16 | const char RIS_CMD_INITPLOT = 6; 17 | const char RIS_CMD_GETPLOT = 7; 18 | const char RIS_CMD_EXIT = 8; 19 | 20 | 21 | const char RIS_REPLY_OK = 101; 22 | const char RIS_REPLY_CALLBACK = 102; 23 | const char RIS_REPLY_VALUE = 103; 24 | const char RIS_REPLY_ERROR = 104; 25 | 26 | 27 | /* 28 | * The Socket protocol is as follows: 29 | * 30 | * The Client initiates the connection by sending the "magic number" 31 | * 32 | * Then the Client sends a CMD, followed by the required parameters. 33 | * The server sends a REPLY, followed by a value, an error or any other 34 | * relevant payload. 35 | * 36 | * For the exact parameters of each command, see rinsideserver.cpp 37 | * 38 | * Communication is continued until the client terminates the connection. The server 39 | * should only terminate the connection when encountering an unrecoverable error. 40 | */ 41 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/common/typeid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Christian Authmann 3 | */ 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* 13 | * We need a value for each type so we can communicate which type to send or receive over the socket. 14 | * 15 | * std::type_info won't help, since its values may change on each program start, making them unsuitable for client/server-communication. 16 | * 17 | * Our typeid is an int32_t. Negative values are reserved for native types (int, float, std::string, ...) while positive values 18 | * can be used in custom classes. See datatypes/foo.h for the syntax. 19 | */ 20 | 21 | namespace typeid_helpers { 22 | /* 23 | * For void_t, see the CppCon2014 talk by Walter E. Brown: "Modern Template Metaprogramming: A Compendium", Part II 24 | */ 25 | template 26 | struct void_t_struct { using type = void; }; 27 | template 28 | using void_t = typename void_t_struct::type; 29 | 30 | 31 | 32 | template 33 | struct has_typeid_member : std::false_type { }; 34 | 35 | template 36 | struct has_typeid_member > : std::true_type { }; 37 | 38 | 39 | /* 40 | * Note: Calling TYPEID() on an unsupported type yields some cryptic compiler errors. If you have seen errors in one of the lines below, 41 | * make sure that the type you're calling TYPEID() on is either 42 | * - a supported native type and has a specialization below 43 | * or 44 | * - a custom class with a public static const int32_t TYPEID 45 | */ 46 | template 47 | struct id { 48 | }; 49 | 50 | template 51 | struct id::value >::type> { 52 | static const int32_t value = T::TYPEID; 53 | }; 54 | 55 | template <> 56 | struct id { 57 | static const int32_t value = 0; 58 | }; 59 | 60 | template <> 61 | struct id { 62 | static const int32_t value = -1; 63 | }; 64 | 65 | template <> 66 | struct id { 67 | static const int32_t value = -2; 68 | }; 69 | 70 | template <> 71 | struct id { 72 | static const int32_t value = -3; 73 | }; 74 | 75 | template <> 76 | struct id { 77 | static const int32_t value = -4; 78 | }; 79 | 80 | template <> 81 | struct id { 82 | static const int32_t value = -5; 83 | }; 84 | 85 | template <> 86 | struct id { 87 | static const int32_t value = -6; 88 | }; 89 | 90 | template <> 91 | struct id { 92 | static const int32_t value = -7; 93 | }; 94 | 95 | template <> 96 | struct id { 97 | static const int32_t value = -8; 98 | }; 99 | 100 | template <> 101 | struct id { 102 | static const int32_t value = -9; 103 | }; 104 | 105 | template <> 106 | struct id { 107 | static const int32_t value = -10; 108 | }; 109 | 110 | template <> 111 | struct id { 112 | static const int32_t value = -11; 113 | }; 114 | 115 | 116 | 117 | template <> 118 | struct id, void> { 119 | static const int32_t value = -21; 120 | }; 121 | 122 | template <> 123 | struct id, void> { 124 | static const int32_t value = -22; 125 | }; 126 | 127 | template <> 128 | struct id, void> { 129 | static const int32_t value = -23; 130 | }; 131 | 132 | template <> 133 | struct id, void> { 134 | static const int32_t value = -24; 135 | }; 136 | 137 | template <> 138 | struct id, void> { 139 | static const int32_t value = -25; 140 | }; 141 | 142 | template <> 143 | struct id, void> { 144 | static const int32_t value = -26; 145 | }; 146 | 147 | template <> 148 | struct id, void> { 149 | static const int32_t value = -27; 150 | }; 151 | 152 | template <> 153 | struct id, void> { 154 | static const int32_t value = -28; 155 | }; 156 | 157 | template <> 158 | struct id, void> { 159 | static const int32_t value = -29; 160 | }; 161 | 162 | template <> 163 | struct id, void> { 164 | static const int32_t value = -30; 165 | }; 166 | 167 | template <> 168 | struct id, void> { 169 | static const int32_t value = -31; 170 | }; 171 | } 172 | 173 | template 174 | constexpr int32_t TYPEID() { 175 | return typeid_helpers::id< typename std::decay::type, void >::value; 176 | } 177 | 178 | 179 | template 180 | struct has_typeid : std::false_type { }; 181 | 182 | template 183 | struct has_typeid::type, void>::value)> > : std::true_type { }; 184 | 185 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/datatypes/bar.cpp: -------------------------------------------------------------------------------- 1 | #include "bar.h" 2 | 3 | Bar::Bar(const std::string &name, const Foo &foo) : name(name), foo(foo) { 4 | 5 | } 6 | Bar::~Bar() { 7 | 8 | } 9 | 10 | void Bar::serialize(BinaryStream &stream) const { 11 | stream.write(name); 12 | stream.write(foo); 13 | } 14 | 15 | Bar Bar::deserialize(BinaryStream &stream) { 16 | auto name = stream.read(); 17 | auto foo = stream.read(); 18 | return Bar(name, foo); 19 | } 20 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/datatypes/bar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * These are just two example classes that will be communicated between program and rserver. 4 | * 5 | * See binarystream.h/.cpp for information about serialization, 6 | * see bar_rcpp_wrapper_*.h for code that converts these objects into R objects and back. 7 | */ 8 | 9 | #include "common/binarystream.h" 10 | #include 11 | #include 12 | 13 | #include "foo.h" 14 | 15 | 16 | /* 17 | * Bar contains a name and a Foo object, because recursive data structures are fun! 18 | */ 19 | class Bar { 20 | public: 21 | Bar(const std::string &name, const Foo &foo); 22 | ~Bar(); 23 | 24 | std::string name; 25 | Foo foo; 26 | 27 | // These three are for IPC 28 | static const int32_t TYPEID = 2; 29 | void serialize(BinaryStream &stream) const; 30 | static Bar deserialize(BinaryStream &stream); 31 | }; 32 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/datatypes/bar_rcpp_wrapper_declarations.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace Rcpp { 5 | 6 | // Bar 7 | template<> SEXP wrap(const Bar &bar); 8 | template<> Bar as(SEXP sexp); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/datatypes/bar_rcpp_wrapper_definitions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | * These wrappers only wrap into a trivial list. More complicated objects should either 5 | * map to a similar 6 | */ 7 | 8 | namespace Rcpp { 9 | 10 | // Bar 11 | template<> SEXP wrap(const Bar &bar) { 12 | Rcpp::List list; 13 | 14 | list["name"] = bar.name; 15 | list["foo"] = bar.foo; 16 | 17 | return Rcpp::wrap(list); 18 | } 19 | template<> Bar as(SEXP sexp) { 20 | Rcpp::List list = Rcpp::as(sexp); 21 | 22 | return Bar( 23 | Rcpp::as(list["name"]), 24 | Rcpp::as(list["foo"]) 25 | ); 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/datatypes/foo.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "foo.h" 3 | 4 | Foo::Foo(const std::string &name, int32_t a, int32_t b) : name(name), a(a), b(b) { 5 | 6 | } 7 | 8 | Foo::~Foo() { 9 | 10 | } 11 | 12 | void Foo::serialize(BinaryStream &stream) const { 13 | stream.write(name); 14 | stream.write(a); 15 | stream.write(b); 16 | } 17 | 18 | 19 | Foo Foo::deserialize(BinaryStream &stream) { 20 | auto name = stream.read(); 21 | auto a = stream.read(); 22 | auto b = stream.read(); 23 | return Foo(name, a, b); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/datatypes/foo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * These are just two example classes that will be communicated between program and rserver. 4 | * 5 | * See common/binarystream.h/.cpp for information about serialization, 6 | * see foo_rcpp_wrapper_*.h for code that converts these objects into R objects and back. 7 | */ 8 | 9 | #include "common/binarystream.h" 10 | #include 11 | #include 12 | 13 | 14 | /* 15 | * Foo just contains a name and two numbers. 16 | */ 17 | class Foo { 18 | public: 19 | Foo(const std::string &name, int32_t a, int32_t b); 20 | ~Foo(); 21 | 22 | std::string name; 23 | int32_t a, b; 24 | 25 | // These three are for IPC 26 | static const int32_t TYPEID = 1; 27 | void serialize(BinaryStream &stream) const; 28 | static Foo deserialize(BinaryStream &stream); 29 | }; 30 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/datatypes/foo_rcpp_wrapper_declarations.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace Rcpp { 5 | // Foo 6 | template<> SEXP wrap(const Foo &foo); 7 | template<> Foo as(SEXP sexp); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/datatypes/foo_rcpp_wrapper_definitions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | * Foo objects are wrapped into a trivial list. More complicated objects should either 5 | * map to a similar native R type or possibly create their own S4 definitions. 6 | */ 7 | 8 | namespace Rcpp { 9 | // Foo 10 | template<> SEXP wrap(const Foo &foo) { 11 | Rcpp::List list; 12 | 13 | list["name"] = foo.name; 14 | list["a"] = foo.a; 15 | list["b"] = foo.b; 16 | 17 | return Rcpp::wrap(list); 18 | } 19 | template<> Foo as(SEXP sexp) { 20 | Rcpp::List list = Rcpp::as(sexp); 21 | 22 | return Foo( 23 | Rcpp::as(list["name"]), 24 | Rcpp::as(list["a"]), 25 | Rcpp::as(list["b"]) 26 | ); 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/server/internalfunction_clone.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | * Ok, frankly, this is a hack. 5 | * We need an InternalFunction, but we don't have a compatible C++ function - we only have 6 | * the parameter count and typeids. 7 | * 8 | * To do this, we need to get down to the point where the function parameters are nothing but an array of SEXP. 9 | * And that's so deep in the CppFunction implementation of Rcpp, that we need some detours to get there. 10 | */ 11 | 12 | 13 | class CppFunctionForRInsideServer: public Rcpp::CppFunctionBase { 14 | public: 15 | CppFunctionForRInsideServer(RInsideServer &server, uint32_t callback_id, const std::vector &types) : server(server), callback_id(callback_id), types(types) { 16 | } 17 | virtual ~CppFunctionForRInsideServer() { 18 | } 19 | SEXP operator()(SEXP* args) { 20 | // TODO: how do we get the amount of arguments passed? We should probably verify them. 21 | BEGIN_RCPP 22 | LOG("Callback %u called", callback_id); 23 | server.sendReply(RIS_REPLY_CALLBACK); 24 | server.stream.write(callback_id); 25 | size_t paramcount = types.size() - 1; 26 | for (size_t i=0;i types; 51 | }; 52 | 53 | // Instantiate the standard deleter. TODO: can we avoid this? 54 | template void Rcpp::standard_delete_finalizer(CppFunctionForRInsideServer* obj); 55 | 56 | 57 | namespace Rcpp{ 58 | 59 | // This is a clone of Rcpp's InternalFunction, just with a different constructor. 60 | RCPP_API_CLASS(InternalFunctionForRInsideServer_Impl) { 61 | public: 62 | 63 | RCPP_GENERATE_CTOR_ASSIGN(InternalFunctionForRInsideServer_Impl) 64 | 65 | InternalFunctionForRInsideServer_Impl(RInsideServer &server, uint32_t callback_id, const std::vector &types) { 66 | set(XPtr(new CppFunctionForRInsideServer(server, callback_id, types), false)); 67 | } 68 | 69 | void update(SEXP){} 70 | private: 71 | 72 | inline void set( SEXP xp){ 73 | Environment RCPP = Environment::Rcpp_namespace() ; 74 | Function intf = RCPP["internal_function"] ; 75 | Storage::set__( intf( xp ) ) ; 76 | } 77 | 78 | }; 79 | 80 | typedef InternalFunctionForRInsideServer_Impl InternalFunctionForRInsideServer ; 81 | 82 | } 83 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/server/rinside_callbacks.h: -------------------------------------------------------------------------------- 1 | class RInsideCallbacks : public Callbacks { 2 | public: 3 | // see inst/includes/Callbacks.h for a list of all overrideable methods 4 | virtual std::string ReadConsole( const char* prompt, bool addtohistory ) { 5 | return ""; 6 | }; 7 | 8 | virtual void WriteConsole( const std::string& line, int type ) { 9 | output_buffer << line; 10 | //printf("Got buffer of type %d: '%s'\n", type, line.c_str()); 11 | }; 12 | 13 | virtual void FlushConsole() { 14 | }; 15 | 16 | virtual void ResetConsole() { 17 | }; 18 | 19 | virtual void CleanerrConsole() { 20 | }; 21 | 22 | virtual void Busy( bool /*is_busy*/ ) { 23 | }; 24 | 25 | virtual void ShowMessage(const char* message) { 26 | //printf("Got Message: '%s'\n", message); 27 | }; 28 | 29 | virtual void Suicide(const char* message) { 30 | LOG("R Suicide: %s", message); 31 | throw std::runtime_error("R suicided"); // TODO: is this the correct way to handle suicides? 32 | }; 33 | 34 | 35 | virtual bool has_ReadConsole() { return true; }; 36 | virtual bool has_WriteConsole() { return true; }; 37 | virtual bool has_FlushConsole(){ return true; }; 38 | virtual bool has_ResetConsole() { return true; }; 39 | virtual bool has_CleanerrConsole() { return true; }; 40 | virtual bool has_Busy() { return true; }; 41 | virtual bool has_ShowMessage() { return true; }; 42 | virtual bool has_Suicide() { return true; }; 43 | 44 | void resetConsoleOutput() { 45 | output_buffer.str(""); 46 | output_buffer.clear(); 47 | } 48 | 49 | std::string getConsoleOutput() { 50 | return output_buffer.str(); 51 | } 52 | private: 53 | std::ostringstream output_buffer; 54 | }; 55 | -------------------------------------------------------------------------------- /inst/examples/sandboxed_server/server/rinsideserver.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Christian Authmann 3 | */ 4 | 5 | #pragma once 6 | 7 | #include "common/typeid.h" 8 | #include "common/binarystream.h" 9 | #include "common/constants.h" 10 | #include "rinside_callbacks.h" 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | class CppFunctionForRInsideServer; 18 | 19 | class RInsideServer { 20 | public: 21 | RInsideServer(BinaryStream &stream, RInside &R, RInsideCallbacks &Rcallbacks); 22 | ~RInsideServer(); 23 | 24 | void run(); 25 | 26 | private: 27 | SEXP sexp_from_stream(); 28 | void sexp_to_stream(SEXP, int32_t type, bool include_reply = false); 29 | 30 | BinaryStream stream; 31 | RInside &R; 32 | RInsideCallbacks &Rcallbacks; 33 | 34 | bool can_send_reply; 35 | void sendReply(char reply) { if (!can_send_reply) throw std::runtime_error("Cannot send a reply at this time, exiting"); can_send_reply = false; stream.write(reply); } 36 | void allowSendReply() { if (can_send_reply) throw std::runtime_error("allowSendReply() called twice, exiting"); can_send_reply = true; } 37 | 38 | static std::map > registry_sexp_from_stream; 39 | static std::map > registry_sexp_to_stream; 40 | 41 | public: 42 | static void registerDefaultTypes(); 43 | template 44 | static void registerType() { 45 | int32_t type = TYPEID(); 46 | 47 | if (registry_sexp_from_stream.count(type) > 0 || registry_sexp_to_stream.count(type) > 0) 48 | throw std::runtime_error("registerType(): type already registered"); 49 | 50 | registry_sexp_from_stream[type] = [] (BinaryStream &stream) -> SEXP { 51 | T value = stream.read(); 52 | return Rcpp::wrap(value); 53 | }; 54 | 55 | registry_sexp_to_stream[type] = [type] (RInsideServer &server, SEXP sexp, bool include_reply) -> void { 56 | T value = Rcpp::as(sexp); 57 | /* 58 | * The reply should be sent after type conversion. If type conversion throws an exception, 59 | * the server cannot reply with REPLY_ERROR after another reply has been sent. 60 | */ 61 | if (include_reply) 62 | server.sendReply(RIS_REPLY_VALUE); 63 | server.stream.write(type); 64 | server.stream.write(value); 65 | }; 66 | } 67 | 68 | friend class CppFunctionForRInsideServer; 69 | }; 70 | -------------------------------------------------------------------------------- /inst/examples/standard/GNUmakefile: -------------------------------------------------------------------------------- 1 | ## 2 | ## Simple Makefile 3 | ## 4 | ## TODO: 5 | ## proper configure for non-Debian file locations, [ Done ] 6 | ## allow RHOME to be set for non-default R etc 7 | 8 | ## comment this out if you need a different version of R, 9 | ## and set set R_HOME accordingly as an environment variable 10 | R_HOME := $(shell R RHOME) 11 | 12 | sources := $(wildcard *.cpp) 13 | programs := $(sources:.cpp=) 14 | 15 | 16 | ## include headers and libraries for R 17 | RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) 18 | RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) 19 | RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) 20 | RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) 21 | 22 | ## if you need to set an rpath to R itself, also uncomment 23 | #RRPATH := -Wl,-rpath,$(R_HOME)/lib 24 | 25 | ## include headers and libraries for Rcpp interface classes 26 | ## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted 27 | RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 28 | RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 29 | 30 | 31 | ## include headers and libraries for RInside embedding classes 32 | RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 33 | RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 34 | 35 | ## compiler etc settings used in default make rules 36 | CXX := $(shell $(R_HOME)/bin/R CMD config CXX) 37 | CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) 38 | CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) 39 | LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) 40 | 41 | all: $(programs) 42 | @test -x /usr/bin/strip && strip $^ 43 | 44 | run: $(programs) 45 | @for p in $(programs); do echo; echo "Running $$p:"; ./$$p; done 46 | 47 | clean: 48 | rm -vf $(programs) 49 | rm -vrf *.dSYM 50 | 51 | runAll: 52 | for p in $(programs); do echo ""; echo ""; echo "Running $$p"; ./$$p; done 53 | -------------------------------------------------------------------------------- /inst/examples/standard/Makefile.win: -------------------------------------------------------------------------------- 1 | ## -*- mode: makefile; tab-width: 8; -*- 2 | ## 3 | ## Simple Makefile for Windows 4 | ## 5 | ## Note that the libRInside library encodes the value of R_HOME found 6 | ## at compilation. So if you use the CRAN package of RInside, its value 7 | ## may not correspond to where you have R installed. One quick fix is 8 | ## export the appropriate value of R_HOME, eg ony my work machine 9 | ## set R_HOME=C:\opt\R-current 10 | ## The other is to re-install RInside from source on your machine. 11 | ## Either one should allow you to actually run the binaries created 12 | ## with this Makefile 13 | 14 | 15 | ## This version is fairly directly derived from the Unix versions 16 | ## You may have to set R_HOME manually if this does not work 17 | ## It requires Rtools in the path -- as does all R package building 18 | R_HOME := $(shell R RHOME | sed -e "s|\\\\|\/|g") 19 | 20 | ## You may have to set this to one of the two values below to enforce a particular 21 | ## architecture in case the autodetection in the next line does not work correctly 22 | R_ARCH := --arch $(shell echo 'cat(.Platform$$r_arch)' | R --vanilla --slave) 23 | ##R_ARCH := --arch i386 24 | ##R_ARCH := --arch x64 25 | 26 | ## You may need to set R_LIBS_USER if Rcpp or RInside are installed where R does not see them by default 27 | #R_LIBS_USER := "C:/myRstuff/library" 28 | 29 | sources := $(wildcard *.cpp) 30 | programs := $(sources:.cpp=) 31 | 32 | ## include headers and libraries for R 33 | RCPPFLAGS := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config --cppflags) 34 | RLDFLAGS := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config --ldflags) 35 | RBLAS := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config BLAS_LIBS) 36 | RLAPACK := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config LAPACK_LIBS) 37 | 38 | 39 | ## include headers and libraries for Rcpp interface classes 40 | RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R $(R_ARCH) --vanilla --slave) 41 | RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R $(R_ARCH) --vanilla --slave) 42 | 43 | 44 | ## include headers and libraries for RInside embedding classes 45 | RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R $(R_ARCH) --vanilla --slave) 46 | RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R $(R_ARCH) --vanilla --slave) 47 | 48 | 49 | ## compiler etc settings used in default make rules 50 | CXX := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config CXX) 51 | CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config CPPFLAGS) 52 | CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config CXXFLAGS) 53 | LDFLAGS = -s 54 | LDLIBS := $(RLDFLAGS) $(RBLAS) $(RLAPACK) $(RINSIDELIBS) $(RCPPLIBS) 55 | CC := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config CXX) 56 | 57 | 58 | all : $(programs) 59 | 60 | clean: 61 | rm -vf $(programs) 62 | 63 | checkR: 64 | echo "R is at $(R_HOME)" 65 | -------------------------------------------------------------------------------- /inst/examples/standard/cmake/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.4) 2 | 3 | set (VERBOSE 1) 4 | set (SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) 5 | 6 | file(GLOB sources ${SRC_DIR}/*.cpp) 7 | 8 | set(NUM_TRUNC_CHARS 2) 9 | 10 | set (RPATH "R") 11 | set (RSCRIPT_PATH "Rscript") 12 | 13 | if (CMAKE_HOST_WIN32) 14 | execute_process(COMMAND ${RSCRIPT_PATH} -e "cat(.Platform$r_arch)" 15 | OUTPUT_VARIABLE R_ARCH) 16 | 17 | execute_process(COMMAND ${RPATH} --arch ${R_ARCH} RHOME 18 | OUTPUT_VARIABLE R_HOME) 19 | 20 | string(REPLACE "\\" "/" R_HOME ${R_HOME}) 21 | 22 | set (RPATH ${R_HOME}/bin/R) 23 | endif() 24 | 25 | set (RCPPFLAGS_CMD " ${RPATH} " " CMD " " config " " --cppflags ") 26 | 27 | execute_process(COMMAND ${RPATH} CMD config --cppflags 28 | OUTPUT_VARIABLE RCPPFLAGS) 29 | 30 | if (CMAKE_HOST_WIN32) 31 | if (${RCPPFLAGS} MATCHES "[-][I]([^ ;])+") 32 | set (RCPPFLAGS ${CMAKE_MATCH_0}) 33 | endif() 34 | endif() 35 | 36 | string(SUBSTRING ${RCPPFLAGS} ${NUM_TRUNC_CHARS} -1 RCPPFLAGS) 37 | include_directories(${RCPPFLAGS}) 38 | 39 | execute_process(COMMAND ${RPATH} CMD config --ldflags 40 | OUTPUT_VARIABLE RLDFLAGS) 41 | string(LENGTH ${RLDFLAGS} RLDFLAGS_LEN) 42 | 43 | if (${RLDFLAGS} MATCHES "[-][L]([^ ;])+") 44 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_L) 45 | string(STRIP ${RLDFLAGS_L} RLDFLAGS_L ) 46 | link_directories(${RLDFLAGS_L} ) 47 | endif() 48 | 49 | if (${RLDFLAGS} MATCHES "[-][l]([^;])+") 50 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_l) 51 | string(STRIP ${RLDFLAGS_l} RLDFLAGS_l ) 52 | endif() 53 | 54 | execute_process(COMMAND ${RSCRIPT_PATH} -e "Rcpp:::CxxFlags()" 55 | OUTPUT_VARIABLE RCPPINCL) 56 | string(SUBSTRING ${RCPPINCL} ${NUM_TRUNC_CHARS} -1 RCPPINCL) 57 | include_directories(${RCPPINCL}) 58 | 59 | execute_process(COMMAND ${RSCRIPT_PATH} -e "Rcpp:::LdFlags()" 60 | OUTPUT_VARIABLE RCPPLIBS) 61 | 62 | execute_process(COMMAND ${RSCRIPT_PATH} -e "RInside:::CxxFlags()" 63 | OUTPUT_VARIABLE RINSIDEINCL) 64 | string(SUBSTRING ${RINSIDEINCL} ${NUM_TRUNC_CHARS} -1 RINSIDEINCL) 65 | include_directories(${RINSIDEINCL}) 66 | 67 | execute_process(COMMAND ${RSCRIPT_PATH} -e "RInside:::LdFlags()" 68 | OUTPUT_VARIABLE RINSIDELIBS) 69 | 70 | if (CMAKE_HOST_WIN32) 71 | string(LENGTH "libRcpp.a" lenRcppName) 72 | string(LENGTH ${RCPPLIBS} lenRcppFQName) 73 | 74 | math(EXPR RLibPathLen ${lenRcppFQName}-${lenRcppName}-1) 75 | string(SUBSTRING ${RCPPLIBS} 0 ${RLibPathLen} RCPPLIBS_L) 76 | link_directories(${RCPPLIBS_L}) 77 | 78 | math(EXPR RLibPathLen ${RLibPathLen}+1) 79 | string(SUBSTRING ${RCPPLIBS} ${RLibPathLen} -1 RCPPLIBS_l) 80 | 81 | #Remove the quotes 82 | string(SUBSTRING ${RINSIDELIBS} 1 -1 RINSIDELIBS) 83 | string(LENGTH ${RINSIDELIBS} lenRInsideFQNameLen) 84 | math(EXPR lenRInsideFQNameLen ${lenRInsideFQNameLen}-1) 85 | string(SUBSTRING ${RINSIDELIBS} 0 ${lenRInsideFQNameLen} RINSIDELIBS) 86 | 87 | string(LENGTH "libRInside.a" lenRInsideName) 88 | string(LENGTH ${RINSIDELIBS} lenRInsideFQName) 89 | 90 | math(EXPR RLibPathLen ${lenRInsideFQName}-${lenRInsideName}-1) 91 | string(SUBSTRING ${RINSIDELIBS} 0 ${RLibPathLen} RINSIDELIBS_L) 92 | 93 | math(EXPR RLibPathLen ${RLibPathLen}+1) 94 | string(SUBSTRING ${RINSIDELIBS} ${RLibPathLen} -1 RINSIDELIBS_l) 95 | 96 | link_directories(${RINSIDELIBS_L}) 97 | else() 98 | if (${RCPPLIBS} MATCHES "[-][L]([^ ;])+") 99 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_L) 100 | link_directories(${RCPPLIBS_L} ) 101 | endif() 102 | 103 | if (${RCPPLIBS} MATCHES "[-][l][R]([^;])+") 104 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_l) 105 | endif() 106 | 107 | if (${RINSIDELIBS} MATCHES "[-][L]([^ ;])+") 108 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_L) 109 | link_directories(${RINSIDELIBS_L}) 110 | endif() 111 | 112 | if (${RINSIDELIBS} MATCHES "[-][l][R]([^;])+") 113 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_l) 114 | endif() 115 | endif() 116 | 117 | execute_process(COMMAND ${RPATH} CMD config CXXFLAGS 118 | OUTPUT_VARIABLE RCXXFLAGS) 119 | 120 | execute_process(COMMAND ${RPATH} CMD config BLAS_LIBS 121 | OUTPUT_VARIABLE RBLAS) 122 | 123 | execute_process(COMMAND ${RPATH} CMD config LAPACK_LIBS 124 | OUTPUT_VARIABLE RLAPACK) 125 | 126 | set(CMAKE_CXX_FLAGS "-W -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}") 127 | 128 | if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR 129 | CMAKE_BUILD_TYPE STREQUAL "RelWithDebugInfo" ) 130 | add_definitions("-DDEBUG") 131 | elseif ( CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) 132 | add_definitions("-O3") 133 | endif() 134 | 135 | foreach (next_SOURCE ${sources}) 136 | get_filename_component(source_name ${next_SOURCE} NAME_WE) 137 | add_executable( ${source_name} ${next_SOURCE} ) 138 | 139 | target_link_libraries(${source_name} ${RLDFLAGS_l}) 140 | target_link_libraries(${source_name} ${BLAS_LIBS}) 141 | target_link_libraries(${source_name} ${LAPACK_LIBS}) 142 | target_link_libraries(${source_name} ${RINSIDELIBS_l}) 143 | target_link_libraries(${source_name} ${RCPPLIBS_l}) 144 | 145 | endforeach (next_SOURCE ${sources}) 146 | -------------------------------------------------------------------------------- /inst/examples/standard/local/rinside_axionator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const char* hello( std::string who ) { 4 | std::string result( "hello ") ; 5 | result += who ; 6 | return result.c_str() ; 7 | } 8 | 9 | int main(int argc, char *argv[]) { 10 | 11 | RInside R(argc, argv); 12 | 13 | R["hello"] = Rcpp::InternalFunction( &hello ); 14 | std::string result = R.parseEval("hello('world')") ; 15 | std::cout << "hello( 'world') = " << result << std::endl ; 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /inst/examples/standard/local/rinside_issue178.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // cf https://github.com/RcppCore/Rcpp/issues/178 4 | 5 | #include // for the embedded R via RInside 6 | 7 | int main(int argc, char *argv[]) { 8 | 9 | try { 10 | 11 | RInside R(argc, argv); // create an embedded R instance 12 | 13 | std::vector data(15); 14 | for_each(data.begin(), data.end(), [](double &val) { val = rand(); }); 15 | //for (int i=0; i<15; i++) data[i] = rand(); 16 | R["data"] = data; 17 | 18 | R.parseEvalQ("print(summary(data))"); 19 | 20 | } catch(std::exception& ex) { 21 | std::cerr << "Exception caught: " << ex.what() << std::endl; 22 | } catch(...) { 23 | std::cerr << "Unknown exception caught" << std::endl; 24 | } 25 | 26 | exit(0); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /inst/examples/standard/local/rinside_slava.cpp: -------------------------------------------------------------------------------- 1 | ////////// dataptr_crash.cpp ////// 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | static boost::shared_ptr Rinst; 8 | 9 | int main(int argc, char *argv[]) { 10 | Rinst = boost::shared_ptr(new RInside(argc, argv)); 11 | const int N = 173; // made const for -Wall .... 12 | double v[N]; 13 | std::fill(v, v+N, 0.0); 14 | Rcpp::NumericVector x(v, v+N); 15 | std::cout << "All good\n"; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /inst/examples/standard/local/rinside_vertica.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | 7 | RInside R(argc, argv); 8 | 9 | R["txt"] = "Hello, world!\n"; 10 | Rcpp::DataFrame pf; // <-------- Runs fine if I comment out this line. 11 | R.parseEvalQ("cat(txt)"); 12 | 13 | exit(0); 14 | } 15 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_callbacks0.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple example showing how to do the standard 'hello, world' using embedded R 4 | // 5 | // Copyright (C) 2009 Dirk Eddelbuettel 6 | // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois 7 | // 8 | // GPL'ed 9 | 10 | #include // for the embedded R via RInside 11 | 12 | int main(int argc, char *argv[]) { 13 | 14 | RInside R(argc, argv); // create an embedded R instance 15 | #if defined(RINSIDE_CALLBACKS) 16 | R.set_callbacks( new Callbacks() ); 17 | R.repl() ; 18 | #endif 19 | exit(0); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_callbacks1.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple example showing how to capture R's console output using callbacks 4 | // 5 | // Copyright (C) 2014 Christian Authmann 6 | // 7 | // GPL'ed 8 | 9 | #include // for the embedded R via RInside 10 | 11 | #if !defined(RINSIDE_CALLBACKS) 12 | int main(int argc, char *argv[]) { 13 | printf("This example requires RInside to be compiled and installed with RINSIDE_CALLBACKS defined\nSee inst/include/RInsideConfig.h\n"); 14 | exit(0); 15 | } 16 | #else 17 | 18 | 19 | class MyCallbacks : public Callbacks { 20 | public: 21 | // see inst/includes/Callbacks.h for a list of all overrideable methods 22 | virtual void WriteConsole( const std::string& line, int type ) { 23 | output_buffer << line << std::endl; 24 | }; 25 | 26 | virtual bool has_WriteConsole() { 27 | return true; 28 | }; 29 | 30 | std::string getConsoleOutput() { 31 | return output_buffer.str(); 32 | } 33 | private: 34 | std::ostringstream output_buffer; 35 | }; 36 | 37 | int main(int argc, char *argv[]) { 38 | MyCallbacks *callbacks = new MyCallbacks(); 39 | 40 | RInside R(argc, argv); // create an embedded R instance 41 | R.set_callbacks( callbacks ); 42 | 43 | R.parseEvalNT("print(\"Hello world\")"); 44 | 45 | std::string result = callbacks->getConsoleOutput(); 46 | printf("R said:\n%s\n", result.c_str()); 47 | exit(0); 48 | } 49 | 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_interactive0.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Example of a planetary motion solver with interactive console 4 | // 5 | // Copyright (C) 2009 Dirk Eddelbuettel 6 | // Copyright (C) 2010 - 2017 Dirk Eddelbuettel and Romain Francois 7 | // Copyright (C) 2017 Dirk Eddelbuettel, Romain Francois and Łukasz Łaniewski-Wołłk 8 | // 9 | // GPL'ed 10 | 11 | #include // for the embedded R via RInside 12 | 13 | class Wrapper; 14 | 15 | // A planet. 16 | struct Planet { 17 | double x,y; 18 | double m; 19 | double vx, vy; 20 | }; 21 | 22 | // A gravity simulator 23 | class Solver { 24 | typedef std::vector Planets; 25 | Planets tab; 26 | double dt; 27 | double G; 28 | void Iteration() { 29 | for (Planets::iterator a=tab.begin(); a != tab.end(); a++) { 30 | for (Planets::iterator b=tab.begin(); b != a; b++) { 31 | double x = a->x - b->x; 32 | double y = a->y - b->y; 33 | double r = sqrt(x*x + y*y); 34 | double f = a->m * b->m * G / (r*r+1); 35 | double fx = f * x/r; 36 | double fy = f * y/r; 37 | a->vx -= dt * fx / a->m; 38 | a->vy -= dt * fy / a->m; 39 | b->vx += dt * fx / b->m; 40 | b->vy += dt * fy / b->m; 41 | } 42 | } 43 | for (Planets::iterator a=tab.begin(); a != tab.end(); a++) { 44 | a->x += dt * a->vx; 45 | a->y += dt * a->vy; 46 | } 47 | } 48 | public: 49 | Solver(int n): tab(n), dt(1.0e-4), G(1.0) { 50 | double v=0; 51 | for (Planets::iterator a=tab.begin(); a != tab.end(); a++) { 52 | a->x = sin(v); 53 | a->y = cos(v); 54 | a->m = 1; 55 | v += 3.0/n; 56 | } 57 | } 58 | void Iterate(int n) { 59 | for (int i=0;itab.begin(); a != s->tab.end(); a++) { 72 | x.push_back( a->x); 73 | y.push_back( a->y); 74 | m.push_back( a->m); 75 | vx.push_back(a->vx); 76 | vy.push_back(a->vy); 77 | } 78 | return Rcpp::DataFrame::create(Rcpp::Named("x") = x, 79 | Rcpp::Named("y") = y, 80 | Rcpp::Named("mass") = m, 81 | Rcpp::Named("Vx") = vx, 82 | Rcpp::Named("Vy") = vy); 83 | } 84 | void setData(Rcpp::DataFrame tab) { 85 | if ((size_t)tab.nrows() != s->tab.size()) { 86 | return; 87 | } 88 | Rcpp::NumericVector x = tab["x"]; 89 | Rcpp::NumericVector y = tab["y"]; 90 | Rcpp::NumericVector m = tab["mass"]; 91 | Rcpp::NumericVector vx = tab["Vy"]; 92 | Rcpp::NumericVector vy = tab["Vy"]; 93 | for (int i=0;itab[i].x = x[i]; 95 | s->tab[i].y = y[i]; 96 | s->tab[i].m = m[i]; 97 | s->tab[i].vx = vx[i]; 98 | s->tab[i].vy = vy[i]; 99 | } 100 | } 101 | double& G() { 102 | return s->G; 103 | } 104 | double& dt() { 105 | return s->dt; 106 | } 107 | }; 108 | 109 | // The function which is called when running Solver$... 110 | SEXP Dollar(Rcpp::XPtr obj, std::string name) { 111 | if (name == "data") { 112 | return obj->getData(); 113 | } else if (name == "G") { 114 | return Rcpp::NumericVector(1,obj->G()); 115 | } else if (name == "dt") { 116 | return Rcpp::NumericVector(1,obj->dt()); 117 | } else { 118 | return NULL; 119 | } 120 | } 121 | 122 | // The function which is called when assigning to Solver$... 123 | Rcpp::XPtr DollarAssign(Rcpp::XPtr obj, std::string name, SEXP v) { 124 | if (name == "data") { 125 | obj->setData(v); 126 | } else if (name == "G") { 127 | obj->G() = Rcpp::NumericVector(v)[0]; 128 | } else if (name == "dt") { 129 | obj->dt() = Rcpp::NumericVector(v)[0]; 130 | } 131 | return obj; 132 | } 133 | 134 | // The function listing the elements of Solver 135 | Rcpp::CharacterVector Names(Rcpp::XPtr obj) { 136 | Rcpp::CharacterVector ret; 137 | ret.push_back("data"); 138 | ret.push_back("G"); 139 | ret.push_back("dt"); 140 | return ret; 141 | } 142 | 143 | int main(int argc, char *argv[]) { 144 | Solver S(70); // Creating the gravity simulator 145 | 146 | RInside R(argc, argv, false, false, true); // Create an embedded R instance 147 | Rcpp::XPtr wr(new Wrapper(&S)); // Wrapping the solver 148 | wr.attr("class") = "Solver"; 149 | R["Solver"] = wr; // Adding the wrapped solver 150 | R["$.Solver"] = Rcpp::InternalFunction(& Dollar); // Adding the functions 151 | R["$<-.Solver"] = Rcpp::InternalFunction(& DollarAssign); 152 | R["names.Solver"] = Rcpp::InternalFunction(& Names); 153 | char type; 154 | do { 155 | std::cout << "Want to go interactive? [y/n]"; 156 | std::cin >> type; 157 | } while ( !std::cin.fail() && type!='y' && type!='n' ); 158 | if (type == 'y') { // Running an interactive R session 159 | std::cout << "Running an interactive R session. You can explore (and modify) the data in the 'Solver' object." << std::endl; 160 | std::cout << "[ You can finish the with Ctrl+D ]" << std::endl; 161 | R.parseEval("options(prompt = 'R console > ')"); 162 | R.parseEval("X11()"); 163 | R.repl() ; 164 | std::cout << "Finishing the interactive mode" << std::endl; 165 | R.parseEval("dev.off()"); 166 | } 167 | R.parseEval("X11()"); 168 | for (int i=0;i<2000;i++) { // Running the some 200'000 iterations in non-interactive mode 169 | S.Iterate(100); 170 | R.parseEval("P = Solver$data;"); 171 | R.parseEval("plot(P$x,P$y,cex=P$mass,asp=1,xlim=c(-5,5),ylim=c(-5,5),xlab='X',ylab='Y')"); 172 | } 173 | exit(0); 174 | } 175 | 176 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_module_sample0.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 4; -*- 2 | // 3 | // Simple example showing how expose a C++ function 4 | // 5 | // Copyright (C) 2010 - 2012 Dirk Eddelbuettel and Romain Francois 6 | 7 | #include // for the embedded R via RInside 8 | 9 | // a c++ function we wish to expose to R 10 | const char* hello( std::string who ){ 11 | std::string result( "hello " ) ; 12 | result += who ; 13 | return result.c_str() ; 14 | } 15 | 16 | // RCPP_MODULE(bling){ 17 | // using namespace Rcpp ; 18 | // function( "hello", &hello ); 19 | // } 20 | 21 | int main(int argc, char *argv[]) { 22 | 23 | // create an embedded R instance -- and load Rcpp so that modules work 24 | RInside R(argc, argv, true); 25 | 26 | // load the bling module 27 | // R["bling"] = LOAD_RCPP_MODULE(bling) ; 28 | 29 | // call it and display the result 30 | Rcpp::Rcout << "** rinside_module_sample0 is currently disabled.\n"; 31 | if (FALSE) { 32 | std::string result = R.parseEval("bling$hello('world')") ; 33 | std::cout << "bling$hello( 'world') = '" << result << "'" << std::endl ; 34 | } 35 | exit(0); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample0.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple example showing how to do the standard 'hello, world' using embedded R 4 | // 5 | // Copyright (C) 2009 Dirk Eddelbuettel 6 | // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois 7 | // 8 | // GPL'ed 9 | 10 | #include // for the embedded R via RInside 11 | 12 | int main(int argc, char *argv[]) { 13 | 14 | RInside R(argc, argv); // create an embedded R instance 15 | 16 | R["txt"] = "Hello, world!\n"; // assign a char* (string) to 'txt' 17 | 18 | R.parseEvalQ("cat(txt)"); // eval the init string, ignoring any returns 19 | 20 | exit(0); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample1.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple example with data in C++ that is passed to R, processed and a result is extracted 4 | // 5 | // Copyright (C) 2009 Dirk Eddelbuettel 6 | // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois 7 | // 8 | // GPL'ed 9 | 10 | #include // for the embedded R via RInside 11 | 12 | Rcpp::NumericMatrix createMatrix(const int n) { 13 | Rcpp::NumericMatrix M(n,n); 14 | for (int i=0; i // for the embedded R via RInside 7 | 8 | void show(const Rcpp::List & L) { 9 | // this function is cumbersome as we haven't defined << operators 10 | std::cout << "Showing list content:\n"; 11 | std::cout << "L[0] " << Rcpp::as(L[0]) << std::endl; 12 | std::cout << "L[1] " << Rcpp::as(L[1]) << std::endl; 13 | Rcpp::IntegerVector v = Rcpp::as(L[2]); 14 | std::cout << "L[2][0] " << v[0] << std::endl; 15 | std::cout << "L[2][1] " << v[1] << std::endl; 16 | } 17 | 18 | int main(int argc, char *argv[]) { 19 | 20 | // create an embedded R instance 21 | RInside R(argc, argv); 22 | 23 | Rcpp::List mylist(3); 24 | mylist[0] = 1; 25 | mylist[1] = 2.5; 26 | Rcpp::IntegerVector v(2); v[0] = 10; v[1] = 11; // with C++0x we could assign directly 27 | mylist[2] = v; 28 | show(mylist); 29 | 30 | R["myRlist"] = mylist; 31 | std::string r_code = "myRlist[[1]] = 42; myRlist[[2]] = 42.0; myRlist[[3]][2] = 42; myRlist"; 32 | 33 | Rcpp::List reslist = R.parseEval(r_code); 34 | show(reslist); 35 | 36 | exit(0); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample11.cpp: -------------------------------------------------------------------------------- 1 | // Simple example motivated by post from Paul Smith 2 | // to r-help on 06 Mar 2011 3 | // 4 | // Copyright (C) 2011 - 2012 Dirk Eddelbuettel and Romain Francois 5 | 6 | #include // for the embedded R via RInside 7 | #include 8 | 9 | int main(int argc, char *argv[]) { 10 | 11 | // create an embedded R instance 12 | RInside R(argc, argv); 13 | 14 | // evaluate an R expression with curve() 15 | // because RInside defaults to interactive=false we use a file 16 | std::string cmd = "tmpf <- tempfile('curve'); " 17 | "png(tmpf); " 18 | "curve(x^2, -10, 10, 200); " 19 | "dev.off();" 20 | "tmpf"; 21 | // by running parseEval, we get the last assignment back, here the filename 22 | std::string tmpfile = R.parseEval(cmd); 23 | 24 | std::cout << "Could now use plot in " << tmpfile << std::endl; 25 | unlink(tmpfile.c_str()); // cleaning up 26 | 27 | // alternatively, by forcing a display we can plot to screen 28 | cmd = "x11(); curve(x^2, -10, 10, 200); Sys.sleep(30);"; 29 | // parseEvalQ evluates without assignment 30 | R.parseEvalQ(cmd); 31 | 32 | exit(0); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample12.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // Simple example motivated by StackOverflow question on using sample() from C 4 | // 5 | // Copyright (C) 2012 Dirk Eddelbuettel and Romain Francois 6 | 7 | #include // for the embedded R via RInside 8 | 9 | int main(int argc, char *argv[]) { 10 | 11 | RInside R(argc, argv); // create an embedded R instance 12 | 13 | std::string cmd = "set.seed(123); sample(LETTERS[1:5], 10, replace=TRUE)"; 14 | 15 | Rcpp::CharacterVector res = R.parseEval(cmd); // parse, eval + return result 16 | 17 | for (int i=0; i(std::cout)); 24 | std::cout << std::endl; 25 | 26 | exit(0); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample13.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // Triggering errors, and surviving to tell the tale 4 | // 5 | // Copyright (C) 2012 Dirk Eddelbuettel and GPL'ed 6 | 7 | #include // for the embedded R via RInside 8 | 9 | int main(int argc, char *argv[]) { 10 | 11 | RInside R(argc, argv); // create an embedded R instance 12 | 13 | try { 14 | std::string cmd = "cat(doesNotExist))"; // simple parse error due to double "))" 15 | R.parseEvalQNT(cmd); // eval quietly, does not throw on error 16 | // parseEvalQ would throw on the error 17 | 18 | cmd = "try(cat(doesNotExist))"; // works also as the try() moderates 19 | R.parseEvalQ(cmd); // eval quietly, no error thrown 20 | // without try() we'd have an error and exit 21 | 22 | cmd = "cat(\"End of main part\\n\")"; 23 | R.parseEval(cmd); // eval the string, ignoring any returns 24 | 25 | } catch( std::exception &ex ) { 26 | std::cerr << "Exception caught: " << ex.what() << std::endl; 27 | } catch(...) { 28 | std::cerr << "C++ exception (unknown reason)" << std::endl; 29 | } 30 | std::cout << "All done, past catch()\n"; 31 | 32 | exit(0); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample14.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // Triggering errors, and surviving to tell the tale 4 | // 5 | // Copyright (C) 2012 Dirk Eddelbuettel and GPL'ed 6 | 7 | #include // for the embedded R via RInside 8 | 9 | int main(int argc, char *argv[]) { 10 | 11 | RInside R(argc, argv, false, false, true); // create an embedded R instance -- and interactive 12 | 13 | try { 14 | std::string cmd = "cat(doesNotExist))"; // simple parse error due to double "))" 15 | R.parseEvalQNT(cmd); // eval quietly, does not throw on error 16 | // parseEvalQ would throw on the error 17 | 18 | cmd = "cat(doesNotExist)"; // error, but surviving as we are in interactive mode 19 | R.parseEvalQ(cmd); // eval quietly, no error thrown 20 | // without try() we'd have an error and exit 21 | 22 | cmd = "cat(\"End of main part\\n\")"; 23 | R.parseEval(cmd); // eval the string, ignoring any returns 24 | 25 | } catch( std::exception &ex ) { 26 | std::cerr << "Exception caught: " << ex.what() << std::endl; 27 | } catch(...) { 28 | std::cerr << "C++ exception (unknown reason)" << std::endl; 29 | } 30 | std::cout << "All done, past catch()\n"; 31 | 32 | exit(0); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample15.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // Creating a lattice plot from RInside 4 | // cf http://stackoverflow.com/questions/24378223/saving-lattice-plots-with-rinside-and-rcpp/ 5 | // 6 | // Copyright (C) 2014 Dirk Eddelbuettel and GPL'ed 7 | 8 | #include // for the embedded R via RInside 9 | #include 10 | 11 | int main(int argc, char *argv[]) { 12 | 13 | // create an embedded R instance 14 | RInside R(argc, argv); 15 | 16 | // evaluate an R expression with curve() 17 | // because RInside defaults to interactive=false we use a file 18 | std::string cmd = "library(lattice); " 19 | "tmpf <- tempfile('xyplot', fileext='.png'); " 20 | "png(tmpf); " 21 | "print(xyplot(Girth ~ Height | equal.count(Volume), data=trees)); " 22 | "dev.off();" 23 | "tmpf"; 24 | 25 | // by running parseEval, we get the last assignment back, here the filename 26 | std::string tmpfile = R.parseEval(cmd); 27 | std::cout << "Can now use plot in " << tmpfile << std::endl; 28 | 29 | exit(0); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample16.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // Simple example showing how expose a C++ function with custom data types 4 | // This is a continuation of rinside_sample9.cpp 5 | // 6 | // Copyright (C) 2014 Christian Authmann 7 | 8 | #include 9 | 10 | /* 11 | * We have a simple data type with two values. 12 | */ 13 | class Foo { 14 | public: 15 | Foo(int a, int b) : a(a), b(b) { 16 | } 17 | ~Foo() { 18 | } 19 | 20 | // The compiler will add the default copy constructor, so this class is copyable. 21 | 22 | int a, b; 23 | }; 24 | 25 | 26 | /* 27 | * We define converters between Foo and R objects, see 28 | * http://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-extending.pdf 29 | */ 30 | #include 31 | /* 32 | * These template declarations must be after RcppCommon.h and before Rcpp.h 33 | * The implementation can follow later, when all of Rcpp/Rinside is available. 34 | */ 35 | namespace Rcpp { 36 | template<> SEXP wrap(const Foo &f); 37 | template<> Foo as(SEXP sexp); 38 | } 39 | 40 | #include 41 | #include 42 | 43 | 44 | /* 45 | * After including Rcpp/Rinside, we can implement the converters. 46 | */ 47 | template<> SEXP Rcpp::wrap(const Foo &f) { 48 | Rcpp::List list; 49 | 50 | list["a"] = f.a; 51 | list["b"] = f.b; 52 | 53 | // Like all internal Rcpp datatypes, the List can be autoconverted to a SEXP, so we can just return it. 54 | // This is equivalent to: return Rcpp::wrap(list) 55 | return list; 56 | } 57 | 58 | template<> Foo Rcpp::as(SEXP sexp) { 59 | Rcpp::List list = Rcpp::as(sexp); 60 | // Note: This does not work when compiled using clang with Rcpp 0.11.2 and older 61 | return Foo( 62 | list["a"], 63 | list["b"] 64 | ); 65 | } 66 | 67 | 68 | // a c++ function we wish to expose to R 69 | Foo swapFoo(Foo &input) { 70 | Foo result(input.b, input.a); 71 | return result; 72 | } 73 | 74 | int main(int argc, char *argv[]) { 75 | 76 | // create an embedded R instance 77 | RInside R(argc, argv); 78 | 79 | // expose the "swapFoo" function in the global environment 80 | R["swapFoo"] = Rcpp::InternalFunction( &swapFoo ); 81 | 82 | // create a foo instance and expose it 83 | Foo f(0, 42); 84 | R["foo"] = f; 85 | 86 | // call it, getting another Foo object 87 | Foo result = R.parseEvalNT( 88 | //"print(foo);" // a=0, b=42 89 | "foo$a = 12;" 90 | //"print(foo);" // a=12, b=42 91 | "foo = swapFoo(foo);" 92 | //"print(foo);" // a=42, b=12 93 | 94 | "foo;" // return the object 95 | ); 96 | 97 | std::cout << " Got result a=" << result.a << ", b=" << result.b << std::endl; 98 | std::cout << " Expected a=42, b=12" << std::endl; 99 | 100 | } 101 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample17.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // More elaborate examples for exposing functions using C++11 4 | // 5 | // Copyright (C) 2014 Christian Authmann 6 | 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | 13 | /* 14 | * We have a simple data type with two values. 15 | * 16 | * Just to make it less simple (and more educational), this class is not copyable, 17 | * preventing it from being used as a function parameter or return type. 18 | */ 19 | class Foo { 20 | public: 21 | Foo(int a, int b) : a(a), b(b) { 22 | } 23 | ~Foo() { 24 | } 25 | 26 | private: 27 | Foo(const Foo &f) : a(f.a), b(f.b) { 28 | throw "Cannot copy construct Foo"; 29 | } 30 | 31 | Foo &operator=(const Foo &f) { 32 | throw "Cannot copy assign Foo"; 33 | } 34 | 35 | public: 36 | int a, b; 37 | }; 38 | 39 | 40 | /* 41 | * We define converters between Foo and R objects, see 42 | * http://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-extending.pdf 43 | * 44 | * These template declarations must be after RcppCommon.h and before Rcpp.h 45 | * The implementation can follow later, when all of Rcpp/Rinside is available. 46 | * 47 | * Since Foo is not copyable, we need a workaround. Instead of passing Foo 48 | * directly, we pass C++11's std::unique_ptr - which is movable. 49 | * Note that the older std::auto_ptr does not work. 50 | */ 51 | namespace Rcpp { 52 | template<> SEXP wrap(const Foo &f); 53 | template<> SEXP wrap(const std::unique_ptr &f); 54 | template<> std::unique_ptr as(SEXP sexp); 55 | } 56 | 57 | #include 58 | #include 59 | 60 | 61 | /* 62 | * After including Rcpp/Rinside, we can implement the converters. 63 | */ 64 | 65 | // An implementation for unique_ptr 66 | template<> SEXP Rcpp::wrap(const std::unique_ptr &f) { 67 | return Rcpp::wrap(*f); 68 | } 69 | 70 | // And an implementation for a non-wrapped object 71 | template<> SEXP Rcpp::wrap(const Foo &f) { 72 | Rcpp::List list; 73 | 74 | list["a"] = f.a; 75 | list["b"] = f.b; 76 | 77 | return Rcpp::wrap(list); 78 | } 79 | 80 | // Converting the R object back to a C++ object will always return a unique_ptr 81 | template<> std::unique_ptr Rcpp::as(SEXP sexp) { 82 | Rcpp::List list = Rcpp::as(sexp); 83 | int a = list["a"]; 84 | int b = list["b"]; 85 | 86 | // With c++14, we'd use std::make_unique(a, b) here 87 | return std::unique_ptr(new Foo(a, b)); 88 | } 89 | 90 | 91 | // C++ functions we wish to expose to R 92 | std::unique_ptr swapFoo(std::unique_ptr input) { 93 | return std::unique_ptr(new Foo(input->b, input->a)); 94 | } 95 | 96 | std::unique_ptr addFoo(std::unique_ptr foo1, std::unique_ptr foo2) { 97 | return std::unique_ptr(new Foo(foo1->a + foo2->a, foo1->b + foo2->b)); 98 | } 99 | 100 | /* 101 | * Let's also assume that we have some kind of data source. We want R scripts to be able 102 | * to query the database without actually exposing the database class. 103 | */ 104 | class FooDatabase { 105 | public: 106 | FooDatabase(int database_id) : database_id(database_id) { 107 | } 108 | // R scripts will want to call this.. 109 | std::unique_ptr queryFoo(int id) { 110 | return std::unique_ptr(new Foo(database_id, id)); 111 | } 112 | // ..but really should not be allowed call this. 113 | void destroyDatabase() { 114 | throw "boom!"; 115 | } 116 | private: 117 | int database_id; 118 | }; 119 | 120 | 121 | int main(int argc, char *argv[]) { 122 | // create an embedded R instance 123 | RInside R(argc, argv); 124 | 125 | // expose the "swapFoo" and "addFoo" functions in the global environment 126 | R["swapFoo"] = Rcpp::InternalFunction( &swapFoo ); 127 | R["addFoo"] = Rcpp::InternalFunction( &addFoo ); 128 | 129 | // We can also expose C++11's std::function, for example to grant access to these three "databases" 130 | FooDatabase db1(1), db2(2), db3(3); 131 | 132 | // All data from DB1 can be queried 133 | std::function< std::unique_ptr(int) > queryDB1 = std::bind(&FooDatabase::queryFoo, std::ref(db1), std::placeholders::_1); 134 | R["queryDB1"] = Rcpp::InternalFunction( queryDB1 ); 135 | 136 | // DB2 shall only be queried with id=42 137 | std::function< std::unique_ptr() > queryDB2 = std::bind(&FooDatabase::queryFoo, std::ref(db2), 42); 138 | R["queryDB2"] = Rcpp::InternalFunction( queryDB2 ); 139 | 140 | // For DB3, let's do some more complicated permission checks. That's a good excuse to use a lambda. 141 | std::function< std::unique_ptr(int) > queryDB3 = 142 | [&db3] (int id) -> std::unique_ptr { 143 | if (id < 0 || id > 20) 144 | throw "id out of allowed range"; 145 | return db3.queryFoo(id); 146 | }; 147 | R["queryDB3"] = Rcpp::InternalFunction( queryDB3 ); 148 | 149 | 150 | std::unique_ptr result = R.parseEvalNT( 151 | "foo1 = queryDB1(20);" 152 | //"print(foo1);" // a=1, b=20 153 | "foo2 = queryDB2();" 154 | //"print(foo2);" // a=2, b=42 155 | "foo3 = queryDB3(10);" 156 | //"print(foo3);" // a=3, b=10 157 | 158 | "foo1 = swapFoo(foo1);" 159 | //"print(foo1);" // a=20, b=1 160 | "foo = addFoo(foo1, addFoo(foo2, foo3));" 161 | //"print(foo);" // a=25, b=53 162 | 163 | "foo;" // return the object 164 | ); 165 | 166 | std::cout << " Got result a=" << result->a << ", b=" << result->b << std::endl; 167 | std::cout << " Expected a=25, b=53" << std::endl; 168 | } 169 | 170 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample2.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple example for the repeated r-devel mails by Abhijit Bera 4 | // 5 | // Copyright (C) 2009 Dirk Eddelbuettel 6 | // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois 7 | 8 | #include // for the embedded R via RInside 9 | 10 | int main(int argc, char *argv[]) { 11 | 12 | try { 13 | RInside R(argc, argv); // create an embedded R instance 14 | 15 | std::string txt = "suppressMessages(library(fPortfolio))"; 16 | R.parseEvalQ(txt); // load library, no return value 17 | 18 | txt = "M <- as.matrix(SWX.RET); print(head(M)); M"; 19 | Rcpp::NumericMatrix M = R.parseEval(txt); // assign mat. M to NumericMatrix 20 | 21 | std::cout << "M has " 22 | << M.nrow() << " rows and " 23 | << M.ncol() << " cols" << std::endl; 24 | 25 | txt = "colnames(M)"; // assign columns names of M to ans and 26 | Rcpp::CharacterVector cnames = R.parseEval(txt); // into str.vec. cnames 27 | 28 | for (int i=0; i // for the embedded R via RInside 9 | #include 10 | 11 | int main(int argc, char *argv[]) { 12 | 13 | RInside R(argc, argv); // create an embedded R instance 14 | 15 | std::string txt = // load library, run regression, create summary 16 | "suppressMessages(require(stats));" 17 | "swisssum <- summary(lm(Fertility ~ . , data = swiss));" 18 | "print(swisssum)"; 19 | R.parseEvalQ(txt); // eval command, no return 20 | 21 | // evaluate R expressions, and assign directly into Rcpp types 22 | Rcpp::NumericMatrix M( (SEXP) R.parseEval("swcoef <- coef(swisssum)")); 23 | Rcpp::StringVector cnames( (SEXP) R.parseEval("colnames(swcoef)")); 24 | Rcpp::StringVector rnames( (SEXP) R.parseEval("rownames(swcoef)")); 25 | 26 | std::cout << "\n\nAnd now from C++\n\n\t\t\t"; 27 | for (int i=0; i // for the embedded R via RInside 9 | #include 10 | 11 | int main(int argc, char *argv[]) { 12 | 13 | try { 14 | RInside R(argc, argv); // create an embedded R instance 15 | 16 | std::string txt = 17 | "suppressMessages(library(fPortfolio)); " 18 | "lppData <- 100 * LPP2005.RET[, 1:6]; " 19 | "ewSpec <- portfolioSpec(); " 20 | "nAssets <- ncol(lppData); "; 21 | R.parseEvalQ(txt); // prepare problem 22 | 23 | const double dvec[6] = { 0.1, 0.1, 0.1, 0.1, 0.3, 0.3 }; // choose any weights 24 | const std::vector w(dvec, &dvec[6]); 25 | R["weightsvec"] = w; // assign weights 26 | txt = "setWeights(ewSpec) <- weightsvec"; 27 | R.parseEvalQ(txt); // evaluate assignment 28 | 29 | txt = 30 | "ewPf <- feasiblePortfolio(data=lppData, spec=ewSpec, constraints=\"LongOnly\");" 31 | "print(ewPf); " 32 | "vec <- getCovRiskBudgets(ewPf@portfolio)"; 33 | Rcpp::NumericVector V( (SEXP) R.parseEval(txt) ); 34 | Rcpp::CharacterVector names( (SEXP) R.parseEval("names(vec)")); 35 | 36 | std::cout << "\n\nAnd now from C++\n\n"; 37 | for (int i=0; i // for the embedded R via RInside 9 | 10 | int main(int argc, char *argv[]) { 11 | 12 | try { 13 | RInside R(argc, argv); // create an embedded R instance 14 | 15 | std::string txt = "myenv <- new.env(hash=TRUE, size=NA)"; 16 | R.parseEvalQ(txt); // eval string quietly, no result 17 | 18 | txt = "is.environment(myenv)"; // logical value assigned 19 | Rcpp::LogicalVector V = R.parseEval(txt); // to logical vector 20 | 21 | std::cout << "We " 22 | << (V(0) ? "do" : "do not") 23 | << " have an environment." << std::endl; 24 | 25 | } catch(std::exception& ex) { 26 | std::cerr << "Exception caught: " << ex.what() << std::endl; 27 | } catch(...) { 28 | std::cerr << "Unknown exception caught" << std::endl; 29 | } 30 | 31 | exit(0); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample6.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Showing off some of the templated conversion due to Rcpp 4 | // 5 | // Copyright (C) 2009 Dirk Eddelbuettel 6 | // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois 7 | 8 | #include // for the embedded R via RInside 9 | 10 | int main(int argc, char *argv[]) { 11 | 12 | try { 13 | 14 | RInside R(argc, argv); // create an embedded R instance 15 | 16 | double d1 = 1.234; // scalar double 17 | R["d1"] = d1; // or R.assign(d1, "d1") 18 | 19 | std::vector d2; // vector of doubles 20 | d2.push_back(1.23); 21 | d2.push_back(4.56); 22 | R["d2"] = d2; // or R.assign(d2, "d2"); 23 | 24 | std::map< std::string, double > d3; // map of doubles 25 | d3["a"] = 7.89; 26 | d3["b"] = 7.07; 27 | R["d3"] = d3; // or R.assign(d3, "d3"); 28 | 29 | std::list< double > d4; // list of doubles 30 | d4.push_back(1.11); 31 | d4.push_back(4.44); 32 | R["d4"] = d4; // or R.assign(d4, "d4"); 33 | 34 | std::string txt = // now access in R 35 | "cat('\nd1=', d1, '\n'); print(class(d1));" 36 | "cat('\nd2=\n'); print(d2); print(class(d2));" 37 | "cat('\nd3=\n'); print(d3); print(class(d3));" 38 | "cat('\nd4=\n'); print(d4); print(class(d4));"; 39 | R.parseEvalQ(txt); 40 | 41 | } catch(std::exception& ex) { 42 | std::cerr << "Exception caught: " << ex.what() << std::endl; 43 | } catch(...) { 44 | std::cerr << "Unknown exception caught" << std::endl; 45 | } 46 | 47 | exit(0); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample7.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Showing off some of the templated as<>() conversion from Rcpp 4 | // 5 | // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois 6 | 7 | #include // for the embedded R via RInside 8 | 9 | int main(int argc, char *argv[]) { 10 | 11 | try { 12 | 13 | RInside R(argc, argv); // create an embedded R instance 14 | std::string txt; 15 | 16 | txt = "m <- 1.23"; 17 | double d1 = Rcpp::as< double >(R.parseEval(txt)); 18 | std::cout << "d1 " << d1 << std::endl; 19 | 20 | txt = "M <- 1.0 * 1:6"; 21 | std::vector d2 = Rcpp::as< std::vector< double > >(R.parseEval(txt)); 22 | std::cout << "d2[0] " << d2[0] << " d2[1] " << d2[1] << std::endl; 23 | 24 | } catch(std::exception& ex) { 25 | std::cerr << "Exception caught: " << ex.what() << std::endl; 26 | } catch(...) { 27 | std::cerr << "Unknown exception caught" << std::endl; 28 | } 29 | 30 | exit(0); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample8.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple example showing how to use R[] = ; 4 | // 5 | // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois 6 | 7 | #include // for the embedded R via RInside 8 | 9 | int main(int argc, char *argv[]) { 10 | 11 | RInside R(argc, argv); // create an embedded R instance 12 | 13 | R["x"] = 10 ; // assignment can be done directly via [] 14 | R["y"] = 20 ; 15 | 16 | R.parseEvalQ("z <- x + y") ; // R statement evaluation and result 17 | int sum = R["z"]; // retrieval via access using [] and implicit wrapper 18 | std::cout << "10 + 20 = " << sum << std::endl ; 19 | 20 | // we can also return the value directly 21 | sum = R.parseEval("x + y") ; 22 | std::cout << "10 + 20 = " << sum << std::endl ; 23 | 24 | exit(0); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_sample9.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple example showing how expose a C++ function -- no longer builds 4 | // 5 | // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois 6 | 7 | #include // for the embedded R via RInside 8 | 9 | // a c++ function we wish to expose to R 10 | std::string hello( std::string who ){ 11 | std::string result( "hello " ) ; 12 | result += who ; 13 | return result; 14 | } 15 | 16 | int main(int argc, char *argv[]) { 17 | 18 | // create an embedded R instance 19 | RInside R(argc, argv); 20 | 21 | // expose the "hello" function in the global environment 22 | R["hello"] = Rcpp::InternalFunction( &hello ) ; 23 | 24 | // call it and display the result 25 | std::string result = R.parseEvalNT("hello(\"world\")") ; 26 | std::cout << "hello( 'world') = " << result << std::endl ; 27 | 28 | exit(0); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_test0.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple test that did not trigger the bug reported by Miguel Lechón 4 | // 5 | // Copyright (C) 2009 - 2014 Dirk Eddelbuettel and GPL'ed 6 | 7 | #include // for the embedded R via RInside 8 | 9 | int main(int argc, char *argv[]) { 10 | 11 | RInside R(argc, argv); // create an embedded R instance 12 | 13 | std::string txt = "Hello, world!\n";// assign a standard C++ string to 'txt' 14 | R["txt"] = txt; // assign string var to R variable 'txt' 15 | 16 | std::string evalstr = "cat(txt)"; 17 | for (int i=0; i<1e1; i++) { 18 | R.parseEvalQ(evalstr); // eval the init string, ignoring any returns 19 | } 20 | evalstr = "txt <- \"foo\\n\""; 21 | for (int i=0; i<1e1; i++) { 22 | R.parseEvalQ(evalstr); // eval the init string, ignoring any returns 23 | } 24 | evalstr = "cat(txt)"; 25 | for (int i=0; i<1e1; i++) { 26 | R.parseEvalQ(evalstr); // eval the init string, ignoring any returns 27 | } 28 | exit(0); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_test1.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- 2 | // 3 | // Simple test that did trigger the bug reported by Miguel Lechón 4 | // 5 | // Copyright (C) 2009 Dirk Eddelbuettel and GPL'ed 6 | 7 | #include // for the embedded R via RInside 8 | 9 | int main(int argc, char *argv[]) { 10 | 11 | RInside R(argc, argv); // create an embedded R instance 12 | 13 | std::string txt = "Hello, world!\n";// assign a standard C++ string to 'txt' 14 | R.assign( txt, "txt"); // assign string var to R variable 'txt' 15 | 16 | std::string evalstr = "txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; cat(txt)"; 17 | for (int i=0; i<1e1; i++) { 18 | R.parseEvalQ(evalstr); // eval the init string, ignoring any returns 19 | } 20 | exit(0); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /inst/examples/standard/rinside_test2.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // Show the search path to check if package methods is loaded 4 | // 5 | // Copyright (C) 2012 Dirk Eddelbuettel and GPL'ed 6 | 7 | #include // for the embedded R via RInside 8 | 9 | int main(int argc, char *argv[]) { 10 | 11 | RInside R(argc, argv); // create an embedded R instance 12 | 13 | std::string cmd = "print(search())"; 14 | R.parseEval(cmd); // eval the init string, ignoring any returns 15 | 16 | exit(0); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /inst/examples/threads/GNUmakefile: -------------------------------------------------------------------------------- 1 | 2 | ## This Makefile is __very__ barebones 3 | ## 4 | ## It works on Debian/Ubuntu. On other systems, add -I and -L flags as needed. 5 | 6 | 7 | ## comment this out if you need a different version of R, 8 | ## and set set R_HOME accordingly as an environment variable 9 | R_HOME := $(shell R RHOME) 10 | 11 | ## include headers and libraries for R 12 | RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) 13 | RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) 14 | RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) 15 | RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) 16 | 17 | ## if you need to set an rpath to R itself, also uncomment 18 | #RRPATH := -Wl,-rpath,$(R_HOME)/lib 19 | 20 | ## include headers and libraries for Rcpp interface classes 21 | RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 22 | RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 23 | 24 | ## include headers and libraries for RInside embedding classes 25 | RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 26 | RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 27 | 28 | 29 | ## minimal Boost libs -- works for me on Ubuntu, may need -L switches elsewhere... 30 | BOOSTLIBS := -lboost_thread 31 | 32 | 33 | ## compiler etc settings used in default make rules 34 | CXX := $(shell $(R_HOME)/bin/R CMD config CXX) 35 | CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) 36 | CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) 37 | LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) $(BOOSTLIBS) 38 | 39 | 40 | 41 | all: boostEx 42 | 43 | boostEx: boostEx.cpp 44 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LDLIBS) 45 | strip $@ 46 | 47 | clean: 48 | rm -f boostEx 49 | -------------------------------------------------------------------------------- /inst/examples/threads/boostEx.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; -*- 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | class Resource { 9 | public: 10 | Resource(): i(0), RR(RInside::instance()) { } 11 | 12 | void use() { 13 | boost::mutex::scoped_lock lock(guard); 14 | RR.parseEvalQ("cat(\"Hello, world from use()\\n\")"); 15 | ++i; 16 | } 17 | int getValue() { return i; } 18 | 19 | private: 20 | int i; 21 | RInside & RR; // reference to embedded R instance 22 | boost::mutex guard; 23 | }; 24 | 25 | void thread_func(Resource& resource) { 26 | resource.use(); 27 | } 28 | 29 | extern uintptr_t R_CStackLimit; 30 | 31 | int main(int argc, char *argv[]) { 32 | 33 | RInside R(argc, argv); 34 | R.parseEvalQ("cat(\"Hello, world from main()\\n\")"); 35 | 36 | Resource resource; 37 | boost::thread_group thread_group; 38 | thread_group.create_thread(boost::bind(thread_func, boost::ref(resource))); 39 | thread_group.create_thread(boost::bind(thread_func, boost::ref(resource))); 40 | thread_group.join_all(); 41 | std::cout << "At end value is " << resource.getValue() << std::endl; 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /inst/examples/wt/GNUmakefile: -------------------------------------------------------------------------------- 1 | 2 | ## This Makefile is __very__ barebones with respect to Wt. 3 | ## 4 | ## It works on Debian/Ubuntu. On other systems, add -I and -L flags as needed. See the cmake use in Wt. 5 | 6 | 7 | ## comment this out if you need a different version of R, 8 | ## and set set R_HOME accordingly as an environment variable 9 | R_HOME := $(shell R RHOME) 10 | 11 | ## include headers and libraries for R 12 | RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) 13 | RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) 14 | RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) 15 | RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) 16 | 17 | ## if you need to set an rpath to R itself, also uncomment 18 | #RRPATH := -Wl,-rpath,$(R_HOME)/lib 19 | 20 | ## include headers and libraries for Rcpp interface classes 21 | RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 22 | RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 23 | 24 | ## include headers and libraries for RInside embedding classes 25 | ## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted 26 | RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) 27 | RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 28 | 29 | 30 | ## minimal Wt libs -- works for me on Ubuntu, may need -L switches elsewhere... 31 | WITTYLIBS := -lwt -lwthttp -lboost_signals -lboost_system 32 | 33 | 34 | ## compiler etc settings used in default make rules 35 | CXX := $(shell $(R_HOME)/bin/R CMD config CXX) 36 | CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) 37 | CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) 38 | LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) $(WITTYLIBS) 39 | 40 | 41 | 42 | all: wtdensity wtdensityPlain 43 | 44 | wtdensityPlain: wtdensityPlain.cpp 45 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LDLIBS) 46 | strip $@ 47 | 48 | wtdensity: wtdensity.cpp 49 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LDLIBS) 50 | strip $@ 51 | 52 | run: wtdensity 53 | ## Wt resources location on Debian/Ubuntu; adjust as needed 54 | test -L resources || ln -s /usr/lib/Wt/resources . 55 | ./$< --docroot "." --http-addr 127.0.0.1 --http-port 8080 56 | 57 | runPlain: wtdensityPlain 58 | ## Wt resources location on Debian/Ubuntu; adjust as needed 59 | test -L resources || ln -s /usr/lib/Wt/resources . 60 | ./$< --docroot "." --http-addr 127.0.0.1 --http-port 8081 61 | 62 | clean: 63 | rm -f wtdensity wtdensityPlain resources 64 | -------------------------------------------------------------------------------- /inst/examples/wt/cmake/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.4) 2 | 3 | set (SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) 4 | 5 | execute_process(COMMAND R RHOME 6 | OUTPUT_VARIABLE R_HOME) 7 | 8 | file(GLOB sources ${SRC_DIR}/*.cpp) 9 | 10 | set(NUM_TRUNC_CHARS 2) 11 | 12 | execute_process(COMMAND R CMD config --cppflags 13 | OUTPUT_VARIABLE RCPPFLAGS) 14 | string(SUBSTRING ${RCPPFLAGS} ${NUM_TRUNC_CHARS} -1 RCPPFLAGS) 15 | include_directories(${RCPPFLAGS}) 16 | 17 | execute_process(COMMAND R CMD config --ldflags 18 | OUTPUT_VARIABLE RLDFLAGS) 19 | string(LENGTH ${RLDFLAGS} RLDFLAGS_LEN) 20 | 21 | if (${RLDFLAGS} MATCHES "[-][L]([^ ;])+") 22 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_L) 23 | string(STRIP ${RLDFLAGS_L} RLDFLAGS_L ) 24 | link_directories(${RLDFLAGS_L} ) 25 | endif() 26 | 27 | if (${RLDFLAGS} MATCHES "[-][l]([^;])+") 28 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_l) 29 | string(STRIP ${RLDFLAGS_l} RLDFLAGS_l ) 30 | endif() 31 | 32 | execute_process(COMMAND Rscript -e "Rcpp:::CxxFlags()" 33 | OUTPUT_VARIABLE RCPPINCL) 34 | string(SUBSTRING ${RCPPINCL} ${NUM_TRUNC_CHARS} -1 RCPPINCL) 35 | include_directories(${RCPPINCL}) 36 | 37 | execute_process(COMMAND Rscript -e "Rcpp:::LdFlags()" 38 | OUTPUT_VARIABLE RCPPLIBS) 39 | if (${RCPPLIBS} MATCHES "[-][L]([^ ;])+") 40 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_L) 41 | link_directories(${RCPPLIBS_L} ) 42 | endif() 43 | 44 | if (${RCPPLIBS} MATCHES "[-][l][R]([^;])+") 45 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_l) 46 | endif() 47 | 48 | execute_process(COMMAND Rscript -e "RInside:::CxxFlags()" 49 | OUTPUT_VARIABLE RINSIDEINCL) 50 | string(SUBSTRING ${RINSIDEINCL} ${NUM_TRUNC_CHARS} -1 RINSIDEINCL) 51 | include_directories(${RINSIDEINCL}) 52 | 53 | execute_process(COMMAND Rscript -e "RInside:::LdFlags()" 54 | OUTPUT_VARIABLE RINSIDELIBS) 55 | if (${RINSIDELIBS} MATCHES "[-][L]([^ ;])+") 56 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_L) 57 | link_directories(${RINSIDELIBS_L}) 58 | endif() 59 | 60 | if (${RINSIDELIBS} MATCHES "[-][l][R]([^;])+") 61 | string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_l) 62 | endif() 63 | 64 | execute_process(COMMAND R CMD config CXXFLAGS 65 | OUTPUT_VARIABLE RCXXFLAGS) 66 | 67 | execute_process(COMMAND R CMD config BLAS_LIBS 68 | OUTPUT_VARIABLE RBLAS) 69 | 70 | execute_process(COMMAND R CMD config LAPACK_LIBS 71 | OUTPUT_VARIABLE RLAPACK) 72 | 73 | set(CMAKE_CXX_FLAGS "-W -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}") 74 | 75 | if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR 76 | CMAKE_BUILD_TYPE STREQUAL "RelWithDebugInfo" ) 77 | add_definitions("-DDEBUG") 78 | elseif ( CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) 79 | add_definitions("-O3") 80 | endif() 81 | 82 | foreach (next_SOURCE ${sources}) 83 | get_filename_component(source_name ${next_SOURCE} NAME_WE) 84 | add_executable( ${source_name} ${next_SOURCE} ) 85 | 86 | target_link_libraries(${source_name} ${RCPPLIBS_l}) 87 | target_link_libraries(${source_name} ${RINSIDELIBS_l}) 88 | target_link_libraries(${source_name} ${RLDFLAGS_l}) 89 | target_link_libraries(${source_name} ${BLAS_LIBS}) 90 | target_link_libraries(${source_name} ${LAPACK_LIBS}) 91 | target_link_libraries(${source_name} "wt") 92 | target_link_libraries(${source_name} "wthttp") 93 | target_link_libraries(${source_name} "boost_signals") 94 | endforeach (next_SOURCE ${sources}) 95 | 96 | -------------------------------------------------------------------------------- /inst/examples/wt/wtdensity.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | font-family: verdana,helvetica,tahoma,sans-serif; 3 | } 4 | 5 | p.p { 6 | margin: 16px 0px; 7 | font-size: smaller; 8 | } 9 | 10 | .box { 11 | margin: 5px 20px; 12 | font-size: smaller; 13 | font-family: sans-serif; 14 | } 15 | 16 | h2 { 17 | padding-left: 30px; 18 | border-bottom: 1px solid #000; 19 | font-size: larger; 20 | } 21 | 22 | h2 span { 23 | border-bottom: 0.2em solid #000; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /inst/examples/wt/wtdensity.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
The data file "{1}" could not be found. Check your deployment.
5 |
6 | 7 | 8 |

Overview

9 | 10 |

11 | This example demonstrates some of the capabilities of the 12 | the Wt library, in combination with the 13 | RInside classes for 14 | embedding the R statistical language and environment. 15 |

16 | 17 |

18 | It reimplements a standard GUI / application setting: 19 | drawing from a random distribution, and estimation a 20 | non-parametric density for which the user selects the kernel and bandwidth. 21 | RInside already contains 22 | an example of this using Qt to provide 23 | a standard application. 24 |

25 | 26 |

27 | Here we show how to do the same in a web application 28 | which, thanks to the abstractions provided by 29 | the Wt, is rather straightforward. 30 |

31 |
32 | 33 | 34 |

User Input for Density Estimation

35 |
36 | 37 | 38 |

User Input for Density Estimation

39 |

40 | The user can select a bandwidth factor (to be divided by 100), 41 | an R expression to generate data (with a default for a mixture 42 | distributions) and a kernel function. 43 |

44 |
45 | 46 | 47 |

Resulting R Chart

48 |
49 | 50 | 51 | 52 |

Resulting R Chart

53 | 54 |

55 | The chart below is created by R given the selected user input. 56 |

57 |
58 | 59 | 60 |

Browser Information

61 |
62 | 63 | 64 |

Browser Information

65 |

66 | The string below is provided by the client's browser and often 67 | reveals operating system and IP address. 68 |

69 |
70 |
-------------------------------------------------------------------------------- /inst/include/Callbacks.h: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 2 | // 3 | // Callbacks.h: R/C++ interface class library -- Easier R embedding into C++ 4 | // 5 | // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois 6 | // 7 | // This file is part of RInside. 8 | // 9 | // RInside is free software: you can redistribute it and/or modify it 10 | // under the terms of the GNU General Public License as published by 11 | // the Free Software Foundation, either version 2 of the License, or 12 | // (at your option) any later version. 13 | // 14 | // RInside is distributed in the hope that it will be useful, but 15 | // WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | // GNU General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU General Public License 20 | // along with RInside. If not, see . 21 | 22 | #ifndef RINSIDE_CALLBACKS_H 23 | #define RINSIDE_CALLBACKS_H 24 | 25 | #include 26 | 27 | #ifdef RINSIDE_CALLBACKS 28 | 29 | class Callbacks { 30 | public: 31 | 32 | Callbacks() : R_is_busy(false), buffer() {} ; 33 | virtual ~Callbacks(){} ; 34 | 35 | virtual void ShowMessage(const char* message) {} ; 36 | virtual void Suicide(const char* message) {}; 37 | virtual std::string ReadConsole( const char* prompt, bool addtohistory ) { return ""; }; 38 | virtual void WriteConsole( const std::string& line, int type ) {}; 39 | virtual void FlushConsole() {}; 40 | virtual void ResetConsole() {}; 41 | virtual void CleanerrConsole(){} ; 42 | virtual void Busy( bool is_busy ) {} ; 43 | 44 | void Busy_( int which ) ; 45 | int ReadConsole_( const char* prompt, unsigned char* buf, int len, int addtohistory ) ; 46 | void WriteConsole_( const char* buf, int len, int oType ) ; 47 | 48 | // TODO: ShowFiles 49 | // TODO: ChooseFile 50 | // TODO: loadHistory 51 | // TODO: SaveHistory 52 | 53 | virtual bool has_ShowMessage() { return false ; } ; 54 | virtual bool has_Suicide() { return false ; } ; 55 | virtual bool has_ReadConsole() { return false ; } ; 56 | virtual bool has_WriteConsole() { return false ; } ; 57 | virtual bool has_ResetConsole() { return false ; } ; 58 | virtual bool has_CleanerrConsole() { return false ; } ; 59 | virtual bool has_Busy() { return false ; } ; 60 | virtual bool has_FlushConsole(){ return false; } ; 61 | 62 | private: 63 | bool R_is_busy ; 64 | std::string buffer ; 65 | 66 | } ; 67 | 68 | #endif 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /inst/include/MemBuf.h: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 2 | // 3 | // MemBuf.h: R/C++ interface class library -- Easier R embedding into C++ 4 | // 5 | // Copyright (C) 2009 Dirk Eddelbuettel 6 | // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois 7 | // 8 | // This file is part of RInside. 9 | // 10 | // RInside is free software: you can redistribute it and/or modify it 11 | // under the terms of the GNU General Public License as published by 12 | // the Free Software Foundation, either version 2 of the License, or 13 | // (at your option) any later version. 14 | // 15 | // RInside is distributed in the hope that it will be useful, but 16 | // WITHOUT ANY WARRANTY; without even the implied warranty of 17 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | // GNU General Public License for more details. 19 | // 20 | // You should have received a copy of the GNU General Public License 21 | // along with RInside. If not, see . 22 | 23 | class MemBuf { // simple C++-ification of littler's membuf 24 | private: 25 | std::string buffer ; 26 | 27 | public: 28 | MemBuf(int sizebytes=1024); 29 | ~MemBuf(); 30 | void resize(); 31 | void rewind(); 32 | void add(const std::string& ); 33 | inline const char* getBufPtr() { return buffer.c_str() ; }; 34 | }; 35 | -------------------------------------------------------------------------------- /inst/include/RInside.h: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 4 -*- 2 | // 3 | // RInside.h: R/C++ interface class library -- Easier R embedding into C++ 4 | // 5 | // Copyright (C) 2009 Dirk Eddelbuettel 6 | // Copyright (C) 2010 - 2017 Dirk Eddelbuettel and Romain Francois 7 | // 8 | // This file is part of RInside. 9 | // 10 | // RInside is free software: you can redistribute it and/or modify it 11 | // under the terms of the GNU General Public License as published by 12 | // the Free Software Foundation, either version 2 of the License, or 13 | // (at your option) any later version. 14 | // 15 | // RInside is distributed in the hope that it will be useful, but 16 | // WITHOUT ANY WARRANTY; without even the implied warranty of 17 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | // GNU General Public License for more details. 19 | // 20 | // You should have received a copy of the GNU General Public License 21 | // along with RInside. If not, see . 22 | 23 | #ifndef RINSIDE_RINSIDE_H 24 | #define RINSIDE_RINSIDE_H 25 | 26 | #include 27 | #include 28 | 29 | class RInside { 30 | private: 31 | MemBuf mb_m; 32 | Rcpp::Environment* global_env_m; 33 | 34 | bool verbose_m; // switch toggled by constructor, or setter 35 | bool interactive_m; // switch set by constructor only 36 | 37 | void init_tempdir(void); 38 | void init_rand(void); 39 | void autoloads(void); 40 | 41 | void initialize(const int argc, const char* const argv[], 42 | const bool loadRcpp, const bool verbose, const bool interactive); 43 | 44 | static RInside* instance_m ; 45 | 46 | #ifdef RINSIDE_CALLBACKS 47 | Callbacks* callbacks ; 48 | friend void RInside_ShowMessage( const char* message); 49 | friend void RInside_WriteConsoleEx( const char* message, int len, int oType ); 50 | friend int RInside_ReadConsole(const char *prompt, unsigned char *buf, int len, int addtohistory); 51 | friend void RInside_ResetConsole(); 52 | friend void RInside_FlushConsole(); 53 | friend void RInside_ClearerrConsole(); 54 | friend void RInside_Busy(int which); 55 | #endif 56 | 57 | public: 58 | 59 | class Proxy { 60 | public: 61 | Proxy(SEXP xx): x(xx) { }; 62 | 63 | template 64 | operator T() { 65 | return ::Rcpp::as(x); 66 | } 67 | private: 68 | Rcpp::RObject x; 69 | }; 70 | 71 | int parseEval(const std::string &line, SEXP &ans); // parse line, return in ans; error code rc 72 | void parseEvalQ(const std::string &line); // parse line, no return (throws on error) 73 | void parseEvalQNT(const std::string &line); // parse line, no return (no throw) 74 | Proxy parseEval(const std::string &line); // parse line, return SEXP (throws on error) 75 | Proxy parseEvalNT(const std::string &line); // parse line, return SEXP (no throw) 76 | 77 | template 78 | void assign(const T& object, const std::string& nam) { 79 | global_env_m->assign( nam, object ) ; 80 | } 81 | 82 | RInside() ; 83 | RInside(const int argc, const char* const argv[], 84 | const bool loadRcpp=true, // overridden in code, cannot be set to false 85 | const bool verbose=false, const bool interactive=false); 86 | ~RInside(); 87 | 88 | void setVerbose(const bool verbose) { verbose_m = verbose; } 89 | 90 | Rcpp::Environment::Binding operator[]( const std::string& name ); 91 | 92 | static RInside& instance(); 93 | static RInside* instancePtr(); 94 | 95 | void repl(); 96 | 97 | #ifdef RINSIDE_CALLBACKS 98 | void set_callbacks(Callbacks* callbacks_) ; 99 | #endif 100 | 101 | }; 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /inst/include/RInsideCommon.h: -------------------------------------------------------------------------------- 1 | 2 | // RInsideCommon.h: R/C++ interface class library -- Easier R embedding into C++ 3 | // 4 | // Copyright (C) 2010 - 2022 Dirk Eddelbuettel and Romain Francois 5 | // 6 | // This file is part of RInside. 7 | // 8 | // RInside is free software: you can redistribute it and/or modify it 9 | // under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 2 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // RInside is distributed in the hope that it will be useful, but 14 | // WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with RInside. If not, see . 20 | 21 | #ifndef RINSIDE_RINSIDECOMMON_H 22 | #define RINSIDE_RINSIDECOMMON_H 23 | 24 | #include 25 | 26 | #include // gettimeofday() 27 | #include // pid_t 28 | #include // getpid() 29 | #include // uint_least64_t (in init_rand()) 30 | 31 | #include // intptr_t (one day we use cinttypes from C++11) 32 | #include // uint64_t (one day we use cstdint from C++11) 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | 40 | #ifdef WIN32 41 | #ifndef Win32 42 | // needed for parts of Rembedded.h 43 | #define Win32 44 | #endif 45 | #endif 46 | 47 | #ifndef WIN32 48 | // needed to turn-off stack checking, and we already have uintptr_t 49 | #define CSTACK_DEFNS 50 | #ifndef HAVE_UINTPTR_T 51 | #define HAVE_UINTPTR_T 52 | #endif 53 | #endif 54 | 55 | #include 56 | #include 57 | 58 | #include 59 | 60 | // simple logging help 61 | inline void logTxtFunction(const char* file, const int line, const char* expression, const bool verbose) { 62 | if (verbose) { 63 | std::cout << file << ":" << line << " expression: " << expression << std::endl; 64 | } 65 | } 66 | 67 | #ifdef logTxt 68 | #undef logTxt 69 | #endif 70 | //#define logTxt(x, b) logTxtFunction(__FILE__, __LINE__, x, b); 71 | #define logTxt(x, b) 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /inst/include/RInsideConfig.h: -------------------------------------------------------------------------------- 1 | // RInsideConfig.h: R/C++ interface class library -- Easier R embedding into C++ 2 | // 3 | // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois 4 | // 5 | // This file is part of RInside. 6 | // 7 | // RInside is free software: you can redistribute it and/or modify it 8 | // under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 2 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // RInside is distributed in the hope that it will be useful, but 13 | // WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with RInside. If not, see . 19 | 20 | #ifndef RINSIDE_RINSIDECONFIG_H 21 | #define RINSIDE_RINSIDECONFIG_H 22 | 23 | // uncomment to turn on the experimental callbacks 24 | // #define RINSIDE_CALLBACKS 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /inst/include/RInside_C.h: -------------------------------------------------------------------------------- 1 | 2 | // RInside_C.h: R/C++ interface class library -- Easier R embedding into C 3 | // 4 | // Copyright (C) 2020 - Lance Bachmeier and Dirk Eddelbuettel 5 | // 6 | // This file is part of RInside. 7 | // 8 | // RInside is free software: you can redistribute it and/or modify it 9 | // under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 2 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // RInside is distributed in the hope that it will be useful, but 14 | // WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with RInside. If not, see . 20 | 21 | #include 22 | 23 | #ifndef RINSIDE_RINSIDE_C_H 24 | #define RINSIDE_RINSIDE_C_H 25 | 26 | void setupRinC(); 27 | void passToR(SEXP x, char * name); 28 | SEXP evalInR(char * cmd); 29 | void evalQuietlyInR(char * cmd); 30 | void teardownRinC(); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /local/qtdensitySVG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/rinside/57e555cdda49bb068880d29d494de431867596c9/local/qtdensitySVG.png -------------------------------------------------------------------------------- /local/runDoxygen: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ ! -d src ]; then 6 | echo "Not above src/" 7 | exit -1 8 | fi 9 | 10 | cwd=$(pwd) 11 | 12 | version=$(r -e'cat(as.character(read.dcf("DESCRIPTION")[,"Version"]))') 13 | echo "Working on version $version" 14 | 15 | 16 | if [ -x /usr/bin/doxygen ]; then 17 | if [ -d inst/doc ]; then 18 | cd inst/doc 19 | rm -rf html/ latex/ man/ 20 | cd ${cwd} 21 | fi 22 | cd src && ln -s ../inst/examples . && cd - 23 | 24 | ## see FAQ 17 for doxygen 25 | ( cat doxyfile ; echo PROJECT_NAME="\"RInside Version ${version}\"" ) | doxygen - 26 | 27 | rm src/examples 28 | cd ${cwd} 29 | pwd 30 | 31 | cd inst/doc 32 | zip -9r rinside-doc-html.zip html/ 33 | zip -9r rinside-doc-man.zip man 34 | zip -9r rinside-doc-latex.zip latex 35 | if [ -d ~/www/code/rinside/ ]; then 36 | mv -v rinside-doc-*.zip ~/www/code/rinside/ 37 | rsync --delete -avu html ~/www/code/rinside/ 38 | fi 39 | cd ${cwd} 40 | 41 | cd inst/doc/latex 42 | pdflatex refman 43 | pdflatex refman 44 | if [ -d ~/www/code/rinside/ ]; then 45 | cp -vax refman.pdf ~/www/code/rinside/RInside_refman.pdf 46 | fi 47 | cd ${cwd} 48 | 49 | if [ -d inst/doc ]; then 50 | cd inst/doc 51 | rm -rf html/ latex/ man/ 52 | cd .. 53 | #rm doc/doxygen_sqlite3.db 54 | rmdir doc 55 | cd ${cwd} 56 | fi 57 | 58 | # if [ -d ~/www/code/rinside/ ]; then 59 | # cp -vax inst/doc/RInside-*.pdf ~/www/code/rinside 60 | # fi 61 | # cd ${cwd} 62 | 63 | fi 64 | -------------------------------------------------------------------------------- /local/wtdensity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/rinside/57e555cdda49bb068880d29d494de431867596c9/local/wtdensity.png -------------------------------------------------------------------------------- /man/RInside-package.Rd: -------------------------------------------------------------------------------- 1 | \name{RInside-package} 2 | \alias{RInside-package} 3 | \alias{RInside} 4 | \docType{package} 5 | \title{Embedding R in C++ applications} 6 | \description{The \pkg{RInside} package makes it easier to embed R 7 | in your C++ applications. There is no code you would execute directly 8 | from the \code{R} environment. Rather, you write \code{C++} programs 9 | that embed \code{R} which is illustrated by some the included examples. 10 | } 11 | \author{Dirk Eddelbuettel and Romain Francois} 12 | \keyword{programming} 13 | \keyword{interface} 14 | -------------------------------------------------------------------------------- /src/Makevars: -------------------------------------------------------------------------------- 1 | ## -*- mode: Makefile; tab-width: 8 -*- 2 | ## 3 | ## Copyright (C) 2010 - 2023 Dirk Eddelbuettel and Romain Francois 4 | ## 5 | ## This file is part of RInside. 6 | ## 7 | ## RInside is free software: you can redistribute it and/or modify it 8 | ## under the terms of the GNU General Public License as published by 9 | ## the Free Software Foundation, either version 2 of the License, or 10 | ## (at your option) any later version. 11 | ## 12 | ## RInside is distributed in the hope that it will be useful, but 13 | ## WITHOUT ANY WARRANTY; without even the implied warranty of 14 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | ## GNU General Public License for more details. 16 | ## 17 | ## You should have received a copy of the GNU General Public License 18 | ## along with RInside. If not, see . 19 | 20 | USERLIB=libRInside$(DYLIB_EXT) 21 | USERLIBST=libRInside.a 22 | USERDIR=../inst/lib 23 | 24 | PKG_CPPFLAGS = -I. -I../inst/include/ 25 | PKG_LIBS = 26 | 27 | all: headers $(SHLIB) userLibrary 28 | 29 | headers: RInsideAutoloads.h RInsideEnvVars.h 30 | 31 | RInsideAutoloads.h: 32 | ${R_HOME}/bin/Rscript tools/RInsideAutoloads.r > RInsideAutoloads.h 33 | 34 | RInsideEnvVars.h: 35 | ${R_HOME}/bin/Rscript tools/RInsideEnvVars.r > RInsideEnvVars.h 36 | 37 | RInside.cpp: headers 38 | 39 | userLibrary: $(USERLIB) $(USERLIBST) 40 | -@if test ! -e $(USERDIR)$(R_ARCH); then mkdir -p $(USERDIR)$(R_ARCH); fi 41 | cp $(USERLIB) $(USERDIR)$(R_ARCH) 42 | cp $(USERLIBST) $(USERDIR)$(R_ARCH) 43 | rm $(USERLIB) $(USERLIBST) 44 | 45 | $(USERLIB): $(OBJECTS) 46 | $(SHLIB_CXXLD) -o $(USERLIB) $^ $(SHLIB_CXXLDFLAGS) $(LDFLAGS) $(ALL_LIBS) 47 | # if we are 48 | # - not on Window NT (a tip from data.table) 49 | # - on macOS aka Darwin which needs this 50 | # - the library is present (implying non-system library use) 51 | # then let us call install_name_tool 52 | @if [ "$(OS)" != "Windows_NT" ] && [ `uname -s` = 'Darwin' ] && test -e "/usr/bin/install_name_tool"; then /usr/bin/install_name_tool -add_rpath @loader_path/../lib$(R_ARCH) $(USERLIB); fi 53 | 54 | $(USERLIBST): $(OBJECTS) 55 | $(AR) qc $(USERLIBST) $^ 56 | @if test -n "$(RANLIB)"; then $(RANLIB) $(USERLIBST); fi 57 | 58 | .PHONY: all clean userLibrary headers 59 | 60 | clean: 61 | rm -f $(OBJECTS) $(SHLIB) $(USERLIB) $(USERLIBST) 62 | -------------------------------------------------------------------------------- /src/Makevars.win: -------------------------------------------------------------------------------- 1 | ## -*- mode: Makefile; tab-width: 8 -*- 2 | ## 3 | ## Copyright (C) 2010 - 2014 Dirk Eddelbuettel and Romain Francois 4 | ## 5 | ## This file is part of RInside. 6 | ## 7 | ## RInside is free software: you can redistribute it and/or modify it 8 | ## under the terms of the GNU General Public License as published by 9 | ## the Free Software Foundation, either version 2 of the License, or 10 | ## (at your option) any later version. 11 | ## 12 | ## RInside is distributed in the hope that it will be useful, but 13 | ## WITHOUT ANY WARRANTY; without even the implied warranty of 14 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | ## GNU General Public License for more details. 16 | ## 17 | ## You should have received a copy of the GNU General Public License 18 | ## along with RInside. If not, see . 19 | 20 | USERLIBST = libRInside.a 21 | USERLIB = libRInside.dll 22 | #USERDIR = $(R_PACKAGE_DIR)/inst/lib$(R_ARCH) 23 | USERDIR = ../inst/lib$(R_ARCH) 24 | 25 | PKG_CPPFLAGS = -I. -I../inst/include/ 26 | PKG_LIBS = $(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" -e "Rcpp:::LdFlags()") 27 | 28 | RSCRIPT = "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" 29 | 30 | all: headers $(SHLIB) userLibrary 31 | 32 | headers: RInsideAutoloads.h RInsideEnvVars.h 33 | 34 | RInsideAutoloads.h: 35 | $(RSCRIPT) tools/RInsideAutoloads.r > RInsideAutoloads.h 36 | 37 | RInsideEnvVars.h: 38 | $(RSCRIPT) tools/RInsideEnvVars.r > RInsideEnvVars.h 39 | 40 | RInside.cpp: headers 41 | 42 | userLibrary: $(USERLIBST) $(USERLIB) 43 | -@if test ! -e $(USERDIR); then mkdir -p $(USERDIR); fi 44 | cp $(USERLIB) $(USERDIR) 45 | 46 | $(USERLIBST): $(OBJECTS) 47 | -@if test ! -e $(USERDIR); then mkdir -p $(USERDIR); fi 48 | $(AR) qc $(USERLIBST) $^ 49 | @if test -n "$(RANLIB)"; then $(RANLIB) $(USERLIBST); fi 50 | cp $(USERLIBST) $(USERDIR) 51 | ls -lR $(USERDIR) 52 | 53 | $(USERLIB): $(OBJECTS) 54 | $(CXX) -Wl,--export-all-symbols -shared -o $(USERLIB) $^ $(ALL_LIBS) -lws2_32 55 | 56 | .PHONY: all clean userLibrary headers 57 | 58 | clean: 59 | rm -f $(OBJECTS) $(SHLIB) $(USERLIBST) $(USERLIB) 60 | 61 | -------------------------------------------------------------------------------- /src/MemBuf.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // MemBuf.cpp: R/C++ interface class library -- Easier R embedding into C++ 4 | // 5 | // Copyright (C) 2009 Dirk Eddelbuettel 6 | // Copyright (C) 2010 - 2012 Dirk Eddelbuettel and Romain Francois 7 | // 8 | // This file is part of RInside. 9 | // 10 | // RInside is free software: you can redistribute it and/or modify it 11 | // under the terms of the GNU General Public License as published by 12 | // the Free Software Foundation, either version 2 of the License, or 13 | // (at your option) any later version. 14 | // 15 | // RInside is distributed in the hope that it will be useful, but 16 | // WITHOUT ANY WARRANTY; without even the implied warranty of 17 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | // GNU General Public License for more details. 19 | // 20 | // You should have received a copy of the GNU General Public License 21 | // along with RInside. If not, see . 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | extern bool verbose; 30 | extern const char *programName; 31 | 32 | MemBuf::~MemBuf() {} 33 | 34 | MemBuf::MemBuf(int sizebytes) : buffer() { 35 | buffer.reserve(sizebytes) ; 36 | } 37 | 38 | void MemBuf::resize() { // Use power of 2 resizing 39 | buffer.reserve( 2*buffer.capacity() ) ; 40 | } 41 | 42 | void MemBuf::rewind(){ 43 | buffer.clear() ; 44 | } 45 | 46 | void MemBuf::add(const std::string& buf){ 47 | int buflen = buf.size() ; 48 | while ( ( buflen + buffer.size() ) >= buffer.capacity() ) { 49 | resize(); 50 | } 51 | buffer += buf ; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/RInside_C.cpp: -------------------------------------------------------------------------------- 1 | 2 | // RInside_C.cpp: R/C++ interface class library -- Easier R embedding into C 3 | // 4 | // Copyright (C) 2020 - Lance Bachmeier and Dirk Eddelbuettel 5 | // 6 | // This file is part of RInside. 7 | // 8 | // RInside is free software: you can redistribute it and/or modify it 9 | // under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 2 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // RInside is distributed in the hope that it will be useful, but 14 | // WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with RInside. If not, see . 20 | 21 | #include 22 | 23 | RInside *rr = NULL; 24 | 25 | extern "C" { 26 | void setupRinC() { 27 | if (rr == NULL) 28 | rr = new RInside; 29 | } 30 | 31 | void passToR(SEXP x, char * name) { 32 | if (rr != NULL) 33 | rr->assign(x, std::string(name)); 34 | } 35 | 36 | SEXP evalInR(char * cmd) { 37 | if (rr != NULL) 38 | return rr->parseEval(std::string(cmd)); 39 | else 40 | return R_NilValue; 41 | } 42 | 43 | void evalQuietlyInR(char * cmd) { 44 | if (rr != NULL) 45 | rr->parseEvalQ(std::string(cmd)); 46 | } 47 | 48 | void teardownRinC() { 49 | if (rr != NULL) { 50 | delete rr; 51 | rr = NULL; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/RcppExports.cpp: -------------------------------------------------------------------------------- 1 | // Generated by using Rcpp::compileAttributes() -> do not edit by hand 2 | // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 3 | 4 | #include "../inst/include/RInside.h" 5 | #include 6 | 7 | using namespace Rcpp; 8 | 9 | // showCompiler 10 | void showCompiler(); 11 | RcppExport SEXP _RInside_showCompiler() { 12 | BEGIN_RCPP 13 | Rcpp::RNGScope rcpp_rngScope_gen; 14 | showCompiler(); 15 | return R_NilValue; 16 | END_RCPP 17 | } 18 | 19 | static const R_CallMethodDef CallEntries[] = { 20 | {"_RInside_showCompiler", (DL_FUNC) &_RInside_showCompiler, 0}, 21 | {NULL, NULL, 0} 22 | }; 23 | 24 | RcppExport void R_init_RInside(DllInfo *dll) { 25 | R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); 26 | R_useDynamicSymbols(dll, FALSE); 27 | } 28 | -------------------------------------------------------------------------------- /src/compiler.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | // [[Rcpp::export]] 5 | void showCompiler() { 6 | #if defined(__DATE__) 7 | const char *date = __DATE__; 8 | #else 9 | const char *date = ""; 10 | #endif 11 | #if defined(__VERSION__) 12 | const char *ver = __VERSION__; 13 | #else 14 | const char *ver = ""; 15 | #endif 16 | Rcpp::Rcout << "Compiled on " << date << " by compiler version " << ver << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /src/setenv/setenv.c: -------------------------------------------------------------------------------- 1 | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 | // 3 | // RInside.cpp: R/C++ interface class library -- Easier R embedding into C++ 4 | // 5 | // Copyright (C) 2009 - 2010 Dirk Eddelbuettel and Richard Holbrey 6 | // Copyright (C) 2012 Dirk Eddelbuettel and Romain Francois 7 | // 8 | // This file is part of RInside. 9 | // 10 | // RInside is free software: you can redistribute it and/or modify it 11 | // under the terms of the GNU General Public License as published by 12 | // the Free Software Foundation, either version 2 of the License, or 13 | // (at your option) any later version. 14 | // 15 | // RInside is distributed in the hope that it will be useful, but 16 | // WITHOUT ANY WARRANTY; without even the implied warranty of 17 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | // GNU General Public License for more details. 19 | // 20 | // You should have received a copy of the GNU General Public License 21 | // along with RInside. If not, see . 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | // borrowed from Renviron.c 28 | extern "C" int setenv(const char *env_var, const char *env_val, int dummy) { 29 | char *buf, *value, *p, *q, *a, *b, quote='\0'; 30 | int inquote = 0; 31 | 32 | //make non-const copies 33 | a = (char *) malloc((strlen(env_var) + 1) * sizeof(char)); 34 | b = (char *) malloc((strlen(env_val) + 1) * sizeof(char)); 35 | if (!a || !b) { 36 | Rf_error("memory allocation failure in setenv"); 37 | } 38 | strcpy(a, env_var); 39 | strcpy(b, env_val); 40 | 41 | buf = (char *) malloc((strlen(a) + strlen(b) + 2) * sizeof(char)); 42 | if (!buf) { 43 | Rf_error("memory allocation failure in setenv"); 44 | } 45 | strcpy(buf, a); strcat(buf, "="); 46 | value = buf+strlen(buf); 47 | 48 | /* now process the value */ 49 | for(p = b, q = value; *p; p++) { 50 | /* remove quotes around sections, preserve \ inside quotes */ 51 | if(!inquote && (*p == '"' || *p == '\'')) { 52 | inquote = 1; 53 | quote = *p; 54 | continue; 55 | } 56 | 57 | if(inquote && *p == quote && *(p-1) != '\\') { 58 | inquote = 0; 59 | continue; 60 | } 61 | 62 | if(!inquote && *p == '\\') { 63 | if(*(p+1) == '\n') { 64 | p++; 65 | } 66 | else if(*(p+1) == '\\') { 67 | *q++ = '/'; 68 | p++; 69 | } 70 | else { 71 | *q++ = '/'; 72 | } 73 | continue; 74 | } 75 | 76 | if(inquote && *p == '\\' && *(p+1) == quote) 77 | continue; 78 | *q++ = *p; 79 | } 80 | *q = '\0'; 81 | //if (putenv(buf)) 82 | //warningcall(R_NilValue, _("problem in setting variable '%s' in Renviron"), a); 83 | return putenv(buf); 84 | 85 | /* no free here: storage remains in use */ 86 | } 87 | 88 | -------------------------------------------------------------------------------- /src/tools/RInsideAutoloads.r: -------------------------------------------------------------------------------- 1 | #!/usr/bin/r 2 | # 3 | # This owes a lot to autoloads.R in the littler sources 4 | 5 | dp <- getOption("defaultPackages") 6 | #dp <- dp[dp != 'datasets'] ## Rscript loads it too 7 | #dp <- dp[dp != 'methods'] ## Rscript (in R 2.6.1) doesn't load methods either 8 | 9 | # Count of default packages 10 | cat(" int packc = ",length(dp),";\n",sep='') 11 | 12 | # List of packages 13 | cat(" const char *pack[] = {\n",paste(' "',dp,'"',sep='',collapse=",\n"),"\n };\n", sep="") 14 | 15 | packobjc <- array(0,dim=length(dp)) 16 | packobj <- NULL 17 | for (i in 1:length(dp)){ 18 | obj = ls(paste("package:",dp[i],sep='')) 19 | packobjc[i] = length(obj) 20 | packobj = c(packobj,obj) 21 | } 22 | 23 | # List of counts of objects per package 24 | cat(" int packobjc[] = {\n ",paste(packobjc,sep='',collapse=",\n "),"\n };\n", sep="") 25 | 26 | # List of object names 27 | cat(" const char *packobj[] = {\n ",paste('"',packobj,'"',sep='',collapse=",\n "),"\n };\n", sep="") 28 | -------------------------------------------------------------------------------- /src/tools/RInsideEnvVars.r: -------------------------------------------------------------------------------- 1 | #!/usr/bin/r -q 2 | # 3 | # This owes a lot to littler.R in the littler sources 4 | 5 | ExcludeVars <- c("R_SESSION_TMPDIR", "R_HISTFILE", "R_LIBRARY_DIR", "R_LIBS", 6 | "R_PACKAGE_DIR", "R_SESSION_INITIALIZED") 7 | IncludeVars <- Sys.getenv() 8 | IncludeVars <- IncludeVars[grep("^R_",names(IncludeVars),perl=TRUE)] 9 | if (.Platform$OS.type == "windows") { 10 | IncludeVars <- gsub("\\\\", "/", IncludeVars, perl=TRUE) 11 | IncludeVars <- gsub("\r", "", IncludeVars, fixed = TRUE) 12 | } 13 | cat(" const char *R_VARS[] = {\n") 14 | for (i in 1:length(IncludeVars)){ 15 | if (names(IncludeVars)[i] %in% ExcludeVars) 16 | next 17 | cat(' "', names(IncludeVars)[i], '", "', 18 | gsub('"', r"(\\")", IncludeVars[i], perl=TRUE), 19 | '",\n', sep='') 20 | } 21 | cat(" NULL\n };\n") 22 | -------------------------------------------------------------------------------- /src/tools/unix2dos.r: -------------------------------------------------------------------------------- 1 | 2 | ## simple 0d 0a -> 0a converter to suppress a warning on Windows 3 | 4 | filename <- commandArgs(trailingOnly=TRUE)[1] 5 | if (!file.exists(filename)) q() 6 | 7 | con <- file(filename, "rb") 8 | bin <- readBin(con, raw(), 100000) 9 | bin <- bin[ which(bin != "0d") ] 10 | close(con) 11 | 12 | Sys.sleep(1) 13 | 14 | con <- file(filename, "wb") 15 | writeBin(bin, con) 16 | close(con) 17 | 18 | --------------------------------------------------------------------------------