[Rcpp-devel] RInline::repl() issues

Dominick Samperi djsamperi at gmail.com
Sun Feb 5 18:46:13 CET 2023


Thanks Simon,

Source code is include this time...

For now RInside::repl() works fine under Windows provided there is no
mouse feedback, and starting the main app using WIN32 GUI
framework is not trivial.

A simple work-around is to implement RInside::repl() as
system("Rterm"), which is what happens when R is
run, but this would make the repl an independent
application, not ideal.

It looks like rtest.c in the front-ends directory is most
applicable (as it uses embeddedR like RInside), but the loop
code there has problems under Windows that led
to the use of run_Rmainloop() instead. Also, this
code does not use WinMain.

I tried embedding the Rterm code (rterm.c,
graphappmain.c, etc.) into the RInside C++ code, but
there were quite a few technical challenges. A simpler
approach where selected parts are used is attached
as repl.cpp.

Here graphappmain.c from src/gnuwin32/front-ends
is embedded (as extern "C") in the original C++ file
repl.cpp, and the WinMain entry point is used (WIN32
API). When NO_WIN32_GRAPHICS_INIT is defined the main
is like it was before (no WIN32 init), and when it is not
defined, WinMain calls GA_startgraphapp(), then calls
AppMain, which calls main. This requires linking to
Rgraphapp.dll.

The repl() function itself is in RInside.cpp, and is
shown below. Several permutations of the init
and looping functions were tried, but with negative
results. Usually the app just terminates.

This is not too surprising given what has been omitted
from the original Rterm build (like rtico.rc resouce file).

repl() from RInside.cpp...

extern "C" {
    extern int GA_initapp(int, char **);
    void setup_Rmainloop(void);
    void run_Rmainloop(void);
    extern void Rf_mainloop(void);
}

void RInside::repl() {
    GA_initapp(0, NULL);
    readconsolecfg();
    //setup_Rmainloop();
    //run_Rmainloop();
    Rf_mainloop();

    // Causes problems under Windows.
    // For example, terminates after plot(0,0)
    // R_ReplDLLinit();
    // while (R_ReplDLLdo1() > 0) {}
}



On Sat, Feb 4, 2023 at 5:58 PM Simon Urbanek <simon.urbanek at r-project.org>
wrote:

> Dominick,
>
> again, it's hard to give you advice when you don't post the code, but note
> that for graphical Windows applications you may need to implement WinMain
> and make sure you setup the Windows event loop (which is separate from R's
> event loop) before you use RInside (see Win32 documentation). You may want
> to to have a look at src/gnuwin32/front-ends in R.
>
> Cheers,
> Simon
>
>
> > On Feb 4, 2023, at 2:02 PM, Dominick Samperi <djsamperi at gmail.com>
> wrote:
> >
> > I'm sorry to say that the RInline::repl() issues are not resolved, and to
> > resolve them would likely require help from R core.
> >
> > Here's the test case:
> > library(sphereplot)
> > rgl.sphgrid(longtype="D")
> >
> > Under Linux there is no problem, a sphere is drawn, and you can
> > rotate with mouse motions.
> >
> > Under Windows using R, no problem.
> >
> > But under Windows in RInline::repl() when you click on the image it
> > freezes up.
> >
> > Apparently some kind of graphics
> > initialization is required, and perhaps callbacks as well to
> > handle mouse events. Just calling run_Rmainloop() is not
> > enough.
> > _______________________________________________
> > Rcpp-devel mailing list
> > Rcpp-devel at lists.r-forge.r-project.org
> > https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20230205/525d95a9/attachment.html>
-------------- next part --------------
//#define NO_WIN32_GRAPHICS_INIT
#ifdef NO_WIN32_GRAPHICS_INIT

// Simple main that uses RInside::repl() without
// Windows graphics initialization. Works ok provided
// there are no mouse events to handle. Entry point is main().
#include <RInside.h>
int main(int argc, char *argv[]) {
    RInside R(argc, argv, false, false, false);
    R.parseEval("options(prompt = 'R > ')");
    R.repl() ;
    exit(0);
}

#else

// Initialize graphics by having Windows use WinMain() entry point,
// and follow graphappmain.c from src/gnuwin32/front-ends.

#include <RInside.h>
int main(int argc, char *argv[]) {
    printf("main called\n");
    RInside R(argc, argv, false, false, false);
    R.parseEval("options(prompt = 'R > ')");
    R.repl() ;
    exit(0);
}

extern "C" {

void AppMain(int argc, char *argv[]) {
    main(argc, argv);
}

// C code graphappmain.c from src/gnuwin32/front-ends    
#include <windows.h>

/* The mingw-runtime startup code has _argc and _argv as visible
   symbols, as do the MS compilers.

   The mingw-w64-crt is different.
*/

extern void 
GA_startgraphapp(HINSTANCE Instance, HINSTANCE PrevInstance, int CmdShow);

    #define _W64
    
int PASCAL
WinMain (HINSTANCE Instance, HINSTANCE PrevInstance, LPSTR CmdLine,
	 int CmdShow)
{
    //extern void AppMain(int argc, char **argv);

#ifdef _W64
    __declspec(dllimport) extern int __argc;
    __declspec(dllimport) extern char **__argv;

    GA_startgraphapp(Instance, PrevInstance, CmdShow);
    AppMain(__argc, __argv);
#else
    __declspec(dllimport) extern int _argc;
    __declspec(dllimport) extern char **_argv;

    GA_startgraphapp(Instance, PrevInstance, CmdShow);
    AppMain(_argc, _argv);
#endif
    return 0;
}

}

#endif


More information about the Rcpp-devel mailing list