From 960883090856eecae1827c69291079062be67503 Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Wed, 27 Apr 2016 08:11:01 +0100 Subject: [PATCH] R DLL/SO not required (!) .. we can register routines when embedding via the R_getEmbeddingDLLInfo() .. so we just register our functions directly now in RTool rather than needing a dynamic library. .. its cleaner and there are no nasty casts and build settings required --- {src/R => deprecated}/RGoldenCheetah.c | 0 src/Core/main.cpp | 6 -- src/R/RTool.cpp | 89 +++++++++++--------------- src/R/RTool.h | 4 -- src/src.pro | 21 ------ 5 files changed, 38 insertions(+), 82 deletions(-) rename {src/R => deprecated}/RGoldenCheetah.c (100%) diff --git a/src/R/RGoldenCheetah.c b/deprecated/RGoldenCheetah.c similarity index 100% rename from src/R/RGoldenCheetah.c rename to deprecated/RGoldenCheetah.c diff --git a/src/Core/main.cpp b/src/Core/main.cpp index bb16c14e2..6779ac06b 100644 --- a/src/Core/main.cpp +++ b/src/Core/main.cpp @@ -270,12 +270,6 @@ main(int argc, char *argv[]) // create the singleton in the main thread // will be shared by all athletes and all charts (!!) rtool = new RTool(argc,argv); - - // and run the .First function - rtool->R->parseEvalQNT(".First()"); - - // now map functions once the DLL is loaded - rtool->registerRoutines(); #endif // create the application -- only ever ONE regardless of restarts diff --git a/src/R/RTool.cpp b/src/R/RTool.cpp index fe5fdb7f0..5337312b6 100644 --- a/src/R/RTool.cpp +++ b/src/R/RTool.cpp @@ -49,6 +49,32 @@ RTool::RTool(int argc, char**argv) R->set_callbacks(callbacks); dev = new RGraphicsDevice(); + // register our functions + + // initialise the parameter table + R_CMethodDef cMethods[] = { + { "GC.display", (DL_FUNC) &RGraphicsDevice::GCdisplay, 0 ,0, 0 }, + { "GC.athlete", (DL_FUNC) &RTool::athlete, 0 ,0, 0 }, + { "GC.athlete.home", (DL_FUNC) &RTool::athleteHome, 0 ,0, 0 }, + { "GC.activities", (DL_FUNC) &RTool::activities, 0 ,0, 0 }, + { "GC.activity", (DL_FUNC) &RTool::activity, 0 ,0, 0 }, + { "GC.metrics", (DL_FUNC) &RTool::metrics, 0 ,0, 0 }, + { NULL, NULL, 0, 0, 0 } + }; + R_CallMethodDef callMethods[] = { + { "GC.display", (DL_FUNC) &RGraphicsDevice::GCdisplay, 0 }, + { "GC.athlete", (DL_FUNC) &RTool::athlete, 0 }, + { "GC.athlete.home", (DL_FUNC) &RTool::athleteHome, 0 }, + { "GC.activities", (DL_FUNC) &RTool::activities, 0 }, + { "GC.activity", (DL_FUNC) &RTool::activity, 0 }, + { "GC.metrics", (DL_FUNC) &RTool::metrics, 0 }, + { NULL, NULL, 0 } + }; + + // set them up + DllInfo *info = R_getEmbeddingDllInfo(); + R_registerRoutines(info, cMethods, callMethods, NULL, NULL); + // lets get the version early for the about dialog R->parseEvalNT("print(R.version.string)"); QStringList &strings = callbacks->getConsoleOutput(); @@ -61,21 +87,18 @@ RTool::RTool(int argc, char**argv) // load the dynamix library and create function wrapper // we should put this into a source file (.R) - R->parseEvalNT(QString(".First <- function() {\n" - " dyn.load(\"RGoldenCheetah.so\")\n" - "}\n" - "GC.display <- function() { .Call(\"GC.display\") }\n" - "GC.athlete <- function() { .Call(\"GC.athlete\") }\n" - "GC.athlete.home <- function() { .Call(\"GC.athlete.home\") }\n" - "GC.activities <- function() { .Call(\"GC.activities\") }\n" - "GC.activity <- function() { .Call(\"GC.activity\") }\n" - "GC.metrics <- function() { .Call(\"GC.metrics\") }\n" - "GC.version <- function() {\n" - " return(\"%1\")\n" - "}\n" - "GC.build <- function() {\n" - " return(%2)\n" - "}\n") + R->parseEvalNT(QString("GC.display <- function() { .Call(\"GC.display\") }\n" + "GC.athlete <- function() { .Call(\"GC.athlete\") }\n" + "GC.athlete.home <- function() { .Call(\"GC.athlete.home\") }\n" + "GC.activities <- function() { .Call(\"GC.activities\") }\n" + "GC.activity <- function() { .Call(\"GC.activity\") }\n" + "GC.metrics <- function() { .Call(\"GC.metrics\") }\n" + "GC.version <- function() {\n" + " return(\"%1\")\n" + "}\n" + "GC.build <- function() {\n" + " return(%2)\n" + "}\n") .arg(VERSION_STRING) .arg(VERSION_LATEST).toStdString()); @@ -113,42 +136,6 @@ RTool::RTool(int argc, char**argv) starting = false; } -extern "C" { -int assigndl(SEXP (**p)(SEXP(*[])()), DL_FUNC x) -{ - *p = (SEXP(*)(SEXP(*[])()))(*x); - return 0; -} - -}; - -void -RTool::registerRoutines() -{ - // the dynamic libray is loaded so we should be able to find - // the initialisation function now - - // get the value - DL_FUNC dd = R_GetCCallable("RGoldenCheetah", "GCinitialiseFunctions"); - - // change signature - SEXP (*p)(SEXP(*[])()); - - // cast - assigndl(&p, dd); - - // array of all the function pointers (just 1 for now) - SEXP (*fn[6])() = { &RGraphicsDevice::GCdisplay, - &RTool::athlete, - &RTool::athleteHome, - &RTool::activities, - &RTool::activity, - &RTool::metrics }; - - // dereference and call, if not found all is lost .... - if (p) *p(fn); -} - void RTool::configChanged() { diff --git a/src/R/RTool.h b/src/R/RTool.h index 0125716b1..d40e89dc2 100644 --- a/src/R/RTool.h +++ b/src/R/RTool.h @@ -48,10 +48,6 @@ class RTool { static SEXP metrics(); bool starting; - - // to link GC.xxx() functions to the routine - // stubs in the RGoldenCheetah DLL/SO/DYLIB - void registerRoutines(); }; // there is a global instance created in main diff --git a/src/src.pro b/src/src.pro index 4ea156bd0..7cfd8746f 100644 --- a/src/src.pro +++ b/src/src.pro @@ -278,27 +278,6 @@ contains(DEFINES, "GC_WANT_R") { HEADERS += Charts/RChart.h Charts/RCanvas.h SOURCES += Charts/RChart.cpp Charts/RCanvas.cpp - # how to build an R shlib from source, listed in SOURCE_RSHLIBS below - # we only have one for now, but could possibly add more. This is to - # use the public R API and avoid using RInside and Rcpp - rshlib.name = rshlib - rshlib.input = SOURCE_RSHLIBS - rshlib.dependency_type = TYPE_C - macx { rshlib.CONFIG += no_link } - unix { rshlib.output = $${OUT_PWD}/${QMAKE_FILE_BASE}.so } - win32 { rshlib.output = $${OUT_PWD}/${QMAKE_FILE_BASE}.dll } - rshlib.commands = $$R_HOME/bin/R CMD SHLIB ${QMAKE_FILE_IN} && $${QMAKE_COPY} ${QMAKE_FILE_PATH}/${QMAKE_FILE_OUT} $${OUT_PWD} - QMAKE_EXTRA_COMPILERS += rshlib - - ## post link on OSX we need to copy the so file - macx { - QMAKE_POST_LINK += $${QMAKE_COPY} $${OUT_PWD}/RGoldenCheetah.so $${OUT_PWD}/GoldenCheetah.app/Contents/MacOS - } - - ## R bootstrap dynamic libraries, used to register C methods - ## to avoid RInside/Rccp - SOURCE_RSHLIBS = R/RGoldenCheetah.c - } }