On 18/08/2009 9:53 AM, Jeffrey J. Hallman wrote:
replying to myself here, in lieu of replying to several others

jhall...@frb.gov (Jeffrey J. Hallman) writes:

One hassle I could do without is the necessity of writing C wrapper functions
like this:

void fameInit(int *status){
  cfmini(status);
  return;
}

when I want to call a library function (cfmini, in this case) that takes an
int argument.  The .C interface only lets me pass a pointer to an int, rather
than the int itself.

Is there any chanch that .C could be enhanced to allow passing arguments by
value to the compiled code?  It would make some of my stuff much simpler.

Of course I realized right after I posted that my example was incorrect.
Since the cfmini() function takes a pointer to an int, all I needed was this:

status <- .C("cfmini", status = as.integer(0))$status

However, I do have functions where this can't be done, because the library
function being called takes one or more parameters by value, not by reference.
For example, I had to write this wrapper:

void fameCloseDatabase(int *status, int *key){
  cfmcldb(status, *key);
  return;
}

where the "key" argument to cfmcldb() is an int, not a pointer.

As you probably realize, cfmcldb() is not something I wrote: it's part of the
FAME Host Language Interface (chli) provided by Sungard, the vendor of the
FAME time series database.

My point, which I clearly did not make very well, since all of the replies so
far have missed it, is that if .C() could pass arguments by value as well as
by reference, I could write the fame package (an interface to the FAME
database) entirely in R, as I'd be able to call any of the chli functions
directly, without having to write C wrappers.  This would make if much easier
to debug the package and get it working correctly on Windows, where I can't
seem to get it to compile correctly any more.  I surely cannot be the only
package writer who has to interface to external libraries and would rather
write the interface in R than in C.

Do we not all see the virtues of doing almost everything in R itself, rather
than writing parts of the system in other languages and systems?  Why else
would Ripley undertake all the recent work to parse .Rd files in R rather than
in Perl, and why do people work on things like gWidgets?

Rd files are now parsed in C, not in R, and the parser was written by me, not by Brian, but you do have a good point: reducing our reliance on external tools that aren't under our control is generally a good thing. It's inconceivable that anyone will do the work to rewrite R not to rely on C, but within a year or two we probably won't rely on Perl.

However, the problem with your suggestion is that it is not at all easy to do. C has a much richer function calling interface than R does. Currently .C supports a minimal part of it, and we could support more, but it isn't at all easy. How do you simulate a general argument list to a C function in C code? (I don't know if it's possible in a portable way.) The current .C implementation has a long list of possible calls: zero args, one arg, two args, etc. If we knew we were working with a specific version of gcc on a specific platform, we could simplify it a lot, but we don't. R compiles on all sorts of different platforms, with compilers using all sorts of different calling conventions. It is just not feasible to write portable code to do general calls.

We could expand the list of calls that we do support, but it's a lot of work, and there would always be someone asking for others. As Doug said, it is not surprising that you need to write interface code - it is
remarkable that it works at all.

Duncan Murdoch



______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to