next up previous contents index
Next: Graphical Interface Tools Up: XLISP-STAT on UNIX Previous: Running UNIX Commands

Dynamic Loading and Foreign Function Calling

   Some UNIX implementations of XLISP-STAT also provide a facility to allow you to use your own C functions of FORTRAN subroutines from within XLISP-STAT. The facility, patterned after the approach used in the New S language [3], consists of the function dyn-load for loading your code into a running XLISP-STAT process and the functions call-cfun, call-fsub and call-lfun for calling subroutines in the loaded code. The dyn-load function requires one argument, a string containing the name of a file to be linked and loaded. The file will be linked with standard C libraries before loading. If you need it to be linked with the standard FORTRAN libraries as well you can give the keyword argument :fortran the value T. Finally, if you need to link other libraries you can supply a string containing the library flags you would specify in a linking command as the value of the keyword argument :libflags. For example, to include the library cmlib use the string "-lcmlib".gif

The function call-cfun takes a string identifying the C function you want to call, followed by additional arguments for your C function. The additional arguments must be integers, sequences of integers, real numbers or sequences of real numbers. Pointers to int or double data containing these values will be passed to your routine. After your routine returns the contents of the data referred to by these pointers are copied into lists and call-cfun returns a list of these lists.

As an example, suppose the file foo.c contains the following C function:

foo(n, x, sum)
     int *n;
     double *x, *sum;
  int i;

  for (i = 0, *sum = 0.0; i < *n; i++) {
    *sum += x[i];
After compiling the file to foo.o we can load it into XLISP-STAT using the expression
(dyn-load "foo.o")
We can then call the function foo using a list of real numbers as the second argument. The function float can be used to coerce numbers to reals:
> (call-cfun "foo" 5 (float (iseq 1 5)) 0.0)
((5) (1 2 3 4 5) (15))
The third argument to foo has been used to return the result.

The function call-fsub is used for calling FORTRAN subroutines that have been loaded dynamically. A FORTRAN subroutine analogous to the C function foo might be written as

      subroutine foo(n, x, sum)
      integer n
      double precision x(n), sum

      integer i

      sum = 0.0
      do 10 i = 1, n
         sum = sum + x(i)
 10   continue
After compiling and loading this routine it can be called using call-fsub:
> (call-fsub "foo" 5 (float (iseq 1 5)) 0.0)
((5) (1 2 3 4 5) (15))

Two C functions you may want to call from within your C functions are xscall_alloc and xscall_fail. The function xscall_alloc is like calloc, except it insures the allocated memory is garbage collected after the call to call-cfun returns. The function xscall_fail takes a character string as its argument. It prints the string and signals an error.

The function call-lfun can be used to call C functions written using the internal XLISP conventions for obtaining arguments and returning results. This allows you to accept any kinds of arguments. Unfortunately, the source code is the only documentation for the internal calling conventions.

A note of caution may be appropriate at this point. Dynamically loaded code contains only the error checking you build into it. If a function is not called with the proper arguments it will most likely cause XLISP-STAT to crash, losing any variables you have not saved.

At present the number of arguments you can pass to C functions or FORTRAN subroutines using call-cfun or call-fsubr is limited to 15.

If dynloading is not available on your system you can still recompile XLISP-STAT with files of your own added to the source code. The functions call-cfun, call-fsubr and call-lfun can be used to call your functions or subroutines in this case as well.

next up previous contents index
Next: Graphical Interface Tools Up: XLISP-STAT on UNIX Previous: Running UNIX Commands

Luke Tierney
Tue Jan 21 15:04:48 CST 1997