| 25857 |
murdoch |
1 |
Writing packages for R
|
|
|
2 |
======================
|
|
|
3 |
|
|
|
4 |
See the Writing R Extensions manual for a full description of how
|
|
|
5 |
to write a package.
|
|
|
6 |
|
| 83561 |
ligges |
7 |
The following content is outdated, but kept here for reference.
|
| 25857 |
murdoch |
8 |
|
| 83561 |
ligges |
9 |
|
|
|
10 |
|
| 9469 |
ripley |
11 |
Building from a source-code library under Windows
|
|
|
12 |
=================================================
|
|
|
13 |
|
| 33027 |
murdoch |
14 |
Instructions for installing the toolset and building packages using the
|
|
|
15 |
standard methods are in the `R Installation and Administration' manual
|
|
|
16 |
(which is available in various formats as R-admin.* in the doc/manual
|
|
|
17 |
directory).
|
| 10545 |
ripley |
18 |
|
| 33027 |
murdoch |
19 |
This file contains instructions for non-standard situations:
|
| 21130 |
ripley |
20 |
|
| 33027 |
murdoch |
21 |
- Using Microsoft Visual C++
|
|
|
22 |
- Using Borland C++
|
|
|
23 |
- Using other compilers and languages
|
| 35733 |
ripley |
24 |
|
| 53374 |
ripley |
25 |
All the examples given here have worked at some point with 32-bit R,
|
|
|
26 |
but are mainly of historical interest.
|
| 37416 |
ripley |
27 |
|
|
|
28 |
|
| 9469 |
ripley |
29 |
Using Visual C++
|
|
|
30 |
================
|
|
|
31 |
|
|
|
32 |
You may if you prefer use Visual C++ to make the DLLs (unless they use
|
| 39939 |
ripley |
33 |
Fortran source!). The notes here were tested with VC++6.
|
| 9469 |
ripley |
34 |
|
| 43404 |
ripley |
35 |
First build the import library Rdll.lib by (from the sources)
|
| 39939 |
ripley |
36 |
|
| 38794 |
ripley |
37 |
make R.exp
|
| 40131 |
ripley |
38 |
|
| 9469 |
ripley |
39 |
lib /def:R.exp /out:Rdll.lib
|
| 40131 |
ripley |
40 |
or, depending on your version of VC++
|
|
|
41 |
link /lib /def:R.exp /machine:x86 /out:Rdll.lib
|
| 9469 |
ripley |
42 |
|
| 43404 |
ripley |
43 |
Another way to make R.exp is to use pexports.exe from mingw-utils,
|
|
|
44 |
e.g. pexports R.dll > R.exp.
|
| 39939 |
ripley |
45 |
|
| 9469 |
ripley |
46 |
Then you can compile the objects and build the DLL by
|
|
|
47 |
|
|
|
48 |
cl /MT /Ox /D "WIN32" /c *.c
|
|
|
49 |
link /dll /def:mypkg.def /out:mypkg.dll *.obj Rdll.lib
|
|
|
50 |
|
|
|
51 |
where you will need to create the .def file by hand listing the entry
|
|
|
52 |
points to be exported. (If there are just a few you can use /export
|
|
|
53 |
flags instead.) If the C sources use R header files you will need to
|
|
|
54 |
arrange for these to be searched, perhaps by including in the cl line
|
|
|
55 |
|
|
|
56 |
/I ..\..\..\include
|
|
|
57 |
|
|
|
58 |
If you build a debug version of the DLL in the development
|
|
|
59 |
environment, you can debug the DLL code there just by setting the
|
|
|
60 |
executable to be debugged as the full path to the R front-end.
|
|
|
61 |
|
| 9940 |
pd |
62 |
Extra care is needed when referencing variables (rather than
|
|
|
63 |
functions) exported from R.dll. These must be declared
|
| 43205 |
ripley |
64 |
__declspec(dllimport) (as in R's own header files).
|
| 9469 |
ripley |
65 |
|
| 43205 |
ripley |
66 |
For some applications making use of the R API headers you will need to
|
|
|
67 |
build import libraries for Rblas.dll or graphapp.dll and link against
|
|
|
68 |
those.
|
|
|
69 |
|
| 40131 |
ripley |
70 |
VC++6 lacks some standard functions such as isnan and isfinite. To use
|
| 29552 |
ripley |
71 |
R's macros you will need
|
| 9940 |
pd |
72 |
|
| 29552 |
ripley |
73 |
#undef ISNAN
|
|
|
74 |
#define ISNAN(x) _isnan(x)
|
|
|
75 |
#undef R_FINITE
|
|
|
76 |
#define R_FINITE(x) _finite(x)
|
|
|
77 |
|
|
|
78 |
for example. Even then, we have seen examples of IEC60559 arithmetic
|
|
|
79 |
being performed incorrectly.
|
|
|
80 |
|
|
|
81 |
|
| 9469 |
ripley |
82 |
Using Borland C++
|
|
|
83 |
=================
|
|
|
84 |
|
|
|
85 |
Borland C++5.5 is available as a free download from
|
|
|
86 |
http://www.borland.com/bcppbuilder/freecompiler/ and as part of C++
|
|
|
87 |
Builder 5. The following will make convolve.dll from convolve.c (flag
|
| 17319 |
ripley |
88 |
-6 optimizes for a Pentium Pro/II/III/4, and -u- removes extra underscores)
|
| 9469 |
ripley |
89 |
|
|
|
90 |
bcc32 -u- -6 -O2 -WDE convolve.c
|
|
|
91 |
|
| 38768 |
ripley |
92 |
You can build an import library for R.dll by
|
| 9469 |
ripley |
93 |
|
| 38794 |
ripley |
94 |
make R.exp
|
|
|
95 |
implib R.lib R.exp
|
| 9469 |
ripley |
96 |
|
|
|
97 |
and then add R.lib to the bcc32 command line, for example (from
|
| 9940 |
pd |
98 |
Venables & Ripley's `S Programming')
|
| 9469 |
ripley |
99 |
|
| 36544 |
ripley |
100 |
bcc32 -u- -6 -O2 -WDE -I\R\R-2.3.0\src\include VCrndR.c R.lib
|
| 9469 |
ripley |
101 |
|
| 10374 |
ripley |
102 |
We believe that when referencing variables (rather than functions)
|
|
|
103 |
exported from R.dll these must be declared __declspec(dllimport) just
|
|
|
104 |
as for VC++.
|
| 9469 |
ripley |
105 |
|
| 9940 |
pd |
106 |
|
| 9469 |
ripley |
107 |
Using other compilers and languages
|
|
|
108 |
===================================
|
|
|
109 |
|
| 9940 |
pd |
110 |
To use C++ see the section in the R for Windows FAQ. You can include
|
| 14462 |
ripley |
111 |
C++ code in packages and the supplied Makefiles will compile with g++
|
| 53374 |
ripley |
112 |
and link the DLL using g++ (and hence link against libstdc++). Use of
|
|
|
113 |
C++ I/O may or may not work, and has been seen to crash R.
|
| 9469 |
ripley |
114 |
|
| 36544 |
ripley |
115 |
To use F90 or F95, see `Writing R Extensions'.
|
|
|
116 |
|
| 9469 |
ripley |
117 |
For other compilers you will need to arrange to produce a DLL with
|
| 51157 |
ripley |
118 |
cdecl (also known as _cdecl or __cdecl) linkage. The MinGW port (and
|
| 14462 |
ripley |
119 |
VC++) uses no `name mangling' at all, so that if for example your
|
| 9469 |
ripley |
120 |
compiler adds leading or trailing underscores you will need to use the
|
|
|
121 |
transformed symbol in the call to .C in your R code. Many compilers
|
|
|
122 |
can produce cdecl DLLs by a suitable choice of flags, but if yours
|
|
|
123 |
cannot you may need to write some `glue' code in C to interface to the
|
|
|
124 |
DLL.
|
|
|
125 |
|
|
|
126 |
If you use .Fortran this appends an underscore and does no case
|
| 53374 |
ripley |
127 |
conversion at all to the symbol name. It is normally best to use .C
|
|
|
128 |
with compilers other than gfortran and map the name manually if
|
|
|
129 |
necessary.
|
| 9469 |
ripley |
130 |
|
|
|
131 |
Care is needed in passing character strings to and from a DLL by .C:
|
|
|
132 |
they must be equivalent to the C type char** and null-terminated. Not
|
| 51157 |
ripley |
133 |
even the MinGW g77 Fortran used null-terminated strings. (g77 was in
|
|
|
134 |
GCC 3.x.y, superseded by gfortran.)
|
| 9469 |
ripley |
135 |
|
| 10374 |
ripley |
136 |
WARNING: DLLs made with some compilers reset the FPU in their startup
|
| 73403 |
murdoch |
137 |
code and this will cause operations such as
|
| 14462 |
ripley |
138 |
0./0. to crash R. You can re-set the FPU to the correct values by a
|
|
|
139 |
call to the C entry point Rwin_fpset().
|
| 9469 |
ripley |
140 |
|