On Sat, 2 Apr 2005, Markku Mielityinen wrote:
Dear Group,
I'm trying to build a set of new graphic device drivers. I use the devNull example a a beginning point:
$ R CMD SHLIB devNull.c gcc -shared -L/usr/local/lib -o devNull.so devNull.o (everything works OK)
$ R CMD SHLIB devNull.cpp g++ -shared -L/usr/local/lib -o devNull.so devNull.o (everything works OK)
Is this the same devNull.cpp as below? If so, I don't believe that it did work.
The difficulties start when trying to compile manually. I compile the library with no errors:
g++ devNull.cpp -o devNull.so -I/usr/lib/R/include -I/usr/local/include -L/usr/local/lib -lm -lpthread -lsupc++ -lg2c -shared -fPIC -O2 -Wall -Wunused -Wconversion -fno-exceptions -g -pipe -m32 -march=i386 -mtune=pentium4
Where did that come from? Why do you need the Fortran runtime linked into C++ code? What has pthreads to do with this?
But when I try to load the library I get:
R : Copyright 2004, The R Foundation for Statistical Computing Version 2.0.1 (2004-11-15), ISBN 3-900051-07-0
R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details.
R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications.
Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for a HTML browser interface to help. Type 'q()' to quit R.
dyn.load("devNull.so")Error in dyn.load(x, as.logical(local), as.logical(now)) : unable to load shared library "/home/mmmm/R/devNull/src/devNull.so": /home/mmmm/R/devNull/src/devNull.so: undefined symbol: _Z17GEinitDisplayListP10_GEDevDesc
I probably need to link to some "libR.a" module.
Please don't hypothesize out of thin air. Nothing there says anything about libR.a. However, it does refer to a symbol you did not call, so you should have noticed that something in the name was amiss.
But where is it? In windows R uses -lR switch but I cannot find that library file in my Fedora Core 3 distribution.
You only need -lR if you built a shared-R-lib version of R, a configure option. If it were needed, R SHLIB would have made use of it.
Notice the name mangling: It seems you are trying to build a C++ graphics device driver. Where did you get the idea that was supported?
You seem unaware how to include C headers in C++ code, but it would be easier to write C as C and not as pseudo-C++.
Is there a file that defines the compiler switches for R CMD SHLIB compiling?
Is there some local tuition about the differences between C and C++ you could obtain?
Here is an example code:
=devNull.cpp============================================================ ======================
#include <R.h> #include <Rinternals.h> #include <Rgraphics.h> #include <Rdevices.h> #include <R_ext/GraphicsDevice.h> #include <R_ext/GraphicsEngine.h>
extern "C" {
static Rboolean nullDeviceDriver(NewDevDesc *dev);
SEXP do_devNULL() { NewDevDesc *dev = NULL; GEDevDesc *dd;
R_CheckDeviceAvailable(); if (!(dev = (NewDevDesc *) calloc(1, sizeof(NewDevDesc)))) return R_NilValue; dev->displayList = R_NilValue; if (!nullDeviceDriver(dev)) { free(dev); error("unable to start NULL device"); } gsetVar(install(".Device"), mkString("NULL"), R_NilValue); dd = GEcreateDevDesc(dev); Rf_addDevice((DevDesc*) dd); GEinitDisplayList(dd); return R_NilValue; } static void NULL_Circle(double x, double y, double r, R_GE_gcontext *gc, NewDevDesc *dev) { Rprintf("circle(%lf,%lf,%lf)\n", x, y, r); } static void NULL_Line(double x1, double y1, double x2, double y2, R_GE_gcontext *gc, NewDevDesc *dev) { Rprintf("line(%lf,%lf,%lf,%lf)\n", x1, y1, x2, y2); } static void NULL_Polygon(int n, double *x, double *y, R_GE_gcontext *gc, NewDevDesc *dev) { Rprintf("polygon(%d)\n", n); } static void NULL_Polyline(int n, double *x, double *y, R_GE_gcontext *gc, NewDevDesc *dev) { Rprintf("polyline(%d)\n", n); } static void NULL_Rect(double x0, double y0, double x1, double y1, R_GE_gcontext *gc, NewDevDesc *dev) { Rprintf("rectangle(%lf,%lf,%lf,%lf)\n", x0, y0, x1, y1); } static void NULL_Text(double x, double y, char *str, double rot, double hadj, R_GE_gcontext *gc, NewDevDesc *dev) { Rprintf("text(%lf,%lf,\"%s\",%lf,%lf)\n", x, y, str, rot, hadj); } static void NULL_NewPage(R_GE_gcontext *gc, NewDevDesc *dev) { Rprintf("newpage\n"); } static void NULL_Close(NewDevDesc *dev) { Rprintf("close\n"); } Rboolean NULL_Open(NewDevDesc *dev) { Rprintf("open\n"); return TRUE; } static void NULL_Activate(NewDevDesc *dev) { Rprintf("activate\n"); } static void NULL_Clip(double x0, double x1, double y0, double y1, NewDevDesc *dev) { Rprintf("clip(%lf,%lf,%lf,%lf)\n", x0, y0, x1, y1); } static void NULL_Deactivate(NewDevDesc *dev) { Rprintf("deactivate\n"); } static void NULL_Mode(int mode, NewDevDesc *dev) { } static Rboolean NULL_Locator(double *x, double *y, NewDevDesc *dev) { return FALSE; } static void NULL_MetricInfo(int c, R_GE_gcontext *gc, double* ascent, double* descent, double* width, NewDevDesc *dev) { *ascent = 0.0; *descent = 0.0; *width = 0.0; } static void NULL_Size(double *left, double *right, double *bottom, double *top, NewDevDesc *dev) { *left = dev->left; *right = dev->right; *bottom = dev->bottom; *top = dev->top; } static double NULL_StrWidth(char *str, R_GE_gcontext *gc, NewDevDesc *dev) { return 0.0; } static void NULL_dot(NewDevDesc *dev) { } static void NULL_Hold(NewDevDesc *dev) { } static Rboolean nullDeviceDriver(NewDevDesc *dev) { dev->deviceSpecific = NULL; /* * Device functions */ dev->open = (Rboolean (*)())NULL_Open; dev->close = (void (*)())NULL_Close; dev->activate = (void (*)())NULL_Activate; dev->deactivate = (void (*)())NULL_Deactivate; dev->size = (void (*)())NULL_Size; dev->newPage = (void (*)())NULL_NewPage; dev->clip = (void (*)())NULL_Clip; dev->strWidth = (double (*)())NULL_StrWidth; dev->text = (void (*)())NULL_Text; dev->rect = (void (*)())NULL_Rect; dev->circle = (void (*)())NULL_Circle; dev->line = (void (*)())NULL_Line; dev->polyline = (void (*)())NULL_Polyline; dev->polygon = (void (*)())NULL_Polygon; dev->locator = (Rboolean (*)())NULL_Locator; dev->mode = (void (*)())NULL_Mode; dev->hold = (void (*)())NULL_Hold; dev->metricInfo = (void (*)())NULL_MetricInfo; /* * Initial graphical settings */ dev->startfont = 1; dev->startps = 10; dev->startcol = R_RGB(0, 0, 0); dev->startfill = R_TRANWHITE; dev->startlty = LTY_SOLID; dev->startgamma = 1; /* * Start device */ if(!NULL_Open(dev)) { return FALSE; } /* * Device physical characteristics */ dev->left = 0; dev->right = 1000; dev->bottom = 0; dev->top = 1000; dev->cra[0] = 10; dev->cra[1] = 10; dev->xCharOffset = 0.4900; dev->yCharOffset = 0.3333; dev->yLineBias = 0.1; dev->ipr[0] = 1.0/72; dev->ipr[1] = 1.0/72; /* * Device capabilities */ dev->canResizePlot= FALSE; dev->canChangeFont= FALSE; dev->canRotateText= TRUE; dev->canResizeText= TRUE; dev->canClip = TRUE; dev->canHAdj = 2; dev->canChangeGamma = FALSE; dev->displayListOn = TRUE;
dev->newDevStruct = 1; return TRUE; }
}
======================================================================== ======================
Best regards, Markku Mielityinen
______________________________________________ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
-- Brian D. Ripley, [EMAIL PROTECTED] Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
______________________________________________ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel