Skip to content

Samples of external code with various compilers?

4 messages · Mark Bravington, Duncan Murdoch, Brian Ripley

#
I can remember hitting several issues with Delphi, that might be applicable
to other languages too. From simple to complicated (in Delphi), these are:

how to write a DLL and export procedures (easy).

how to declare parameters (VAR or pointers to arrays; pretty simple).

how arrays of >1 dimension map to R arrays (easy).

what call mode to use for procedures (i.e. stack order and removal of
parameters; I had always used STDCALL with S and R, and then found I was
getting bugs with R 1.6.1. So in desperation I eventually changed this at
random to C-CALL, and things started working again in R-- and continued to
work in S. To my continued puzzlement, actually.)

how to handle & return character strings (The only way I've found to return
a string of unknown length, was to call a Delphi function twice; the first
time it merely returns the number of characters in the string. Then create a
string of spaces of the correct length in R, and explicitly put that string
in a .C call to the Delphi function, which this time can fill in the actual
characters.)

how to get the Delphi debugger to work on a DLL being called by R. This is
incredibly easy in S but rather difficult in R, because of a quirk to do
with starting directories.

Then there are one or two tricks I've sometimes used: e.g. how to return a
Delphi pointer to R so that a "persistent" Delphi object can be created with
one call to a Delphi function from R, then accessed again on a subsequent
call. Useful even with simple things like returning a string, and essential
with really complex structures. All languages will have their own tricks,
which are well worth some informal documentation somewhere.

And then there is the business of turning the R headers into Delphi
equivalents-- a work in progress.

cheers
Mark

*******************************

Mark Bravington
CSIRO (CMIS)
PO Box 1538
Castray Esplanade
Hobart
TAS 7001

phone (61) 3 6232 5118
fax (61) 3 6232 5012
Mark.Bravington@csiro.au 

#-----Original Message-----
#From: Duncan Murdoch [mailto:murdoch@stats.uwo.ca]
#Sent: Tuesday, 3 December 2002 1:15 AM
#To: ripley@stats.ox.ac.uk
#Cc: r-devel@stat.math.ethz.ch
#Subject: Re: [Rd] Samples of external code with various compilers?
#
#
#On Mon, 2 Dec 2002 08:07:19 +0000 (GMT), you wrote in message
#<Pine.LNX.4.31.0212020753570.1625-100000@gannet.stats>:
#
#>I think there is information and lots of examples already for 
#Fortran. 
#
#I was thinking of two additions:
#
# 1.  Rewriting the samples in sections 4.2 and/or 4.5 in Fortran,
#Delphi, etc.  I might make them a little more elaborate, e.g. showing
#how to return a character string.
#
# 2.  Write up the details of how to do it in various specific
#compilers.  For example, if you're using Microsoft Visual Fortran, how
#do you create a DLL, how do you set the exported entry points, what
#bugs do you need to work around.
#
#>Base R has only interfaces for C and Fortran (and that via C-style
#>linkage): SJava adds .Java.  So is the issue how to write in other
#>languages to use a C interface?  `how to dyn.load functions' 
#is easy: you
#>just create an appropriate compiled object, a shared library, 
#a DLL or (on
#>MacOS X as I understand it) a module.  The issues seem to be 
#to export the
#>symbols correctly, and even more to import ones from R correctly.
#
#Yes, that's the main issue.  There are also issues even with C:  if
#you're using some compiler other than gcc, you probably won't compile
#using R SHLIB, so what do you need to do?
#
#Duncan
#
#______________________________________________
#R-devel@stat.math.ethz.ch mailing list
#http://www.stat.math.ethz.ch/mailman/listinfo/r-devel
#
#
On Tue, 3 Dec 2002 Mark.Bravington@csiro.au wrote:

            
(Most of these are Windows-specific.)
Well, that *is* documented.  For R in readme.packages under `Using other
compilers and languages' which is quite a short section.  So if people
don't read what is already there, is there any point in expanding it?

It's also documented for S-PLUS (if that is what you mean by `S': it
reflects a lot of work by Insightful on top of Lucent S4).

[...]
#
On Tue, 3 Dec 2002 10:01:08 +1100 , Mark.Bravington@csiro.au wrote:

            
The difference between stdcall and cdecl is that in the former, the
routine removes parameters from the stack, whereas in the latter, the
caller does.

R uses cdecl.  When the routine used stdcall, the parameters would be
removed twice.  My guess about why this worked was that the
"do_dotCode" routine had enough redundant locals that having some of
them removed from the stack didn't cause obvious problems.  In 1.6,
do_dotCode was modified, and now it messes up if you steal its locals.

Most other Windows programs use stdcall.  Using the stdcall convention
to call a cdecl routine means that the parameters won't be removed
from the stack by either the caller or the routine.  However, S-PLUS
is probably like R, and only makes one call to your routine from the
function that calls it.  When it returns, the extra junk on the stack
is removed.

Since stdcall is the Windows standard, and R uses cdecl, I've been
thinking lately about whether it would be worth putting in stdcall as
an option to .C and .Fortran.  Possibly we could just switch to
stdcall, and rely on the behaviour in the paragraph above to handle
cdecl routines, but that sounds pretty ugly to me.

Duncan Murdoch
#
On Tue, 3 Dec 2002, Duncan Murdoch wrote:

            
S-PLUS 2000 was like R.  S-PLUS 6 is cleverer and tries to figure out
(from the decoration on the symbol, I believe) if stdcall or cdecl is
required, but it defaults to stdcall.
You can't because of callbacks into R from the compiled code.  That's
where the problems arise with S-PLUS 6: such callbacks have to be stdcall
there.

stdcall requires that all the calls have the right number and type of
parameters.  That's really difficult to check with Fortran code (or with C
code with incomplete headers).  Working with S-PLUS 6 has been much more
error-prone precisely because of the use of stdcall, and I don't see it as
a way forward.