
		       External function calls


(GET-EXTERNAL string)
Returns an external pointer to the given name.  A null will be added to the
end of the name if there isn't already one.

(LOOKUP-ALL-EXTERNALS)
Looks up all externals in the currently job.  Ideally this should be called
automatically on startup.

(EXTERNAL-CALL external arg1 arg2 ...)
Calls the external value, passing it the number of arguments (as a long),
and a pointer to a C array containing the rest of the arguments (also
a long).  Don't mess with the array, it is really the Scheme 48 argument
stack.  The arguments are probably in reverse order, I can't remember.

(NULL-TERMINATE string)


The file dynload.c contains the function s48_dynamic_load which can
be called using EXTERNAL-CALL.  To make it work you need to do the
following:

 1) If you're using ultrix, link the VM using -N.

 2) When invoking the VM, use the -o flag to pass it the name of the
    executable file containing the VM.  [This is done automatically by
    the shell script created by "make".]

 3) If your OS supports shared libraries, do as appropriate to arrange
    for your C code to be position-independent and to create a shared
    library.

If dynamic loading doesn't work you can always link the external stuff
in with the VM.  The dynamic loading code has problems.  I am not much
of a Unix hacker.

Here is a transcript on SunOS 4.something:

    kama$ gcc -fpic -c test.c
    kama$ /bin/ld -assert pure-text -o test.so test.o
    kama$ file test.so
    test.so:	sparc demand paged shared library executable not stripped
    kama$ 
    kama$ scheme48
    Welcome to Scheme 48 0.31 (made by jar on Sun Feb 13 18:33:57 EST 1994).
    Copyright (c) 1993, 1994 by Richard Kelsey and Jonathan Rees.
    Please report bugs to scheme-48-bugs@altdorf.ai.mit.edu.
    Type ,? (comma question-mark) for help.
    > ,open externals
    Load structure externals (y/n)? y
    [externals
    /usr/public/sun4/lib/scheme48/big/external.scm ..............
    ]
    > (define dynamic-load (get-external "s48_dynamic_load"))
    > (external-call dynamic-load (null-terminate "test.so"))
    #t
    > (define test (get-external "test"))
    > (external-call test "yow" 3)
    string: yow
    fixnum: 3
    #t
    > 

If using cc instead of gcc, do "cc -pic -c ...".

(get-external "_s48_dynamic_load") and (get-external "_test") might be
required on some versions of Unix (like maybe SGI).

Here is file test.c:

    #include "/usr/local/include/scheme48.h"
    #include <stdio.h>

    scheme_value test ()
         long argc; scheme_value *argv;
    {
      int i; 
      for (i = argc-1; i >= 0; i--) {
	scheme_value arg = argv[i];
	if (STRINGP(arg)) {
	  printf ("string: ");
	  fwrite(&STRING_REF(arg, 0), 1, STRING_LENGTH(arg), stdout);
	  printf ("\n");
	}
	else if (FIXNUMP(arg)) {
	  printf("fixnum: %d\n", EXTRACT_FIXNUM(arg));
	}
	else
	  printf("?\n");
      }
      return SCHTRUE;
    }
