[Rd] Building new graphic device drivers with g++
Markku Mielityinen
mmmm at pp.inet.fi
Sat Apr 2 12:31:55 CEST 2005
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)
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
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. But where is it? In
windows R uses -lR switch but I cannot find that library file in my
Fedora Core 3 distribution.
Is there a file that defines the compiler switches for R CMD SHLIB
compiling?
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
More information about the R-devel
mailing list