Dear Gambit enthusiasts,
I think I figured out how to use dlopen to run functions from Gambit that live in dynamically loaded libraries (plugins); my best to date is below.
But I'm not quite happy with it--because it's kind of elaborate.  That is, I couldn't figure out how to avoid some of the boiler plate below.  Perhaps there is a shorter way?
So my question for Gambit enthusiasts is: Is there a cleaner way to do this--to run functions from plugin libraries? i.e. without having to pre-declare call_plugin_print8 and call_print8.  What if you wanted to make such a call after inspecting a new library at runtime?
Many thanks!  Gambit rocks!  Thanks again for such a great system.
- Jason
;;;;;;;;;;;;;;;  file: libex.cpp  ;;;;;;;;;;;;
;
;                 a simple library of one function for 
;                 testing/development of plugin loading  
;
#include <stdio.h>
extern "C" int print8() {
  printf("\n In print8() : returning 8\n"); 
  return 8; 
}
;;;;;;;;;;;;;;;  file: libex.h   ;;;;;;;;;;;;
#ifndef LIBEX_H
#define LIBEX_H
int print8();
#endif
;;;;;;;;;;;;;;;  file:  dlopen.scm   ;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  dlopen.scm : plugins in Gambit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; compile and link with:
;
; gsc -link dlopen.scm
; gcc -I/usr/local/Gambit-C/include -L/usr/local/Gambit-C/lib  dlopen.c  dlopen_.c  -lgambc -lm -lutil -ldl -o dlopen
(c-declare #<<c-declare-end
       #include <stdio.h>
       #include <stdlib.h>
       #include <dlfcn.h>
       #include "libex.h"
       /* simple wrapper to do runtime plugin function calls (call into .so library) */
       int call_plugin_print8(void* handle) {
         char *error;
         int (*my_func)();
         // my_func               = (int (*)()) dlsym(handle,"print8");
         *(void **) (&my_func) = dlsym(handle, "print8");
     if ((error = dlerror()) != NULL)  
     {
         fprintf(stderr, "%s\n", error);
         exit(EXIT_FAILURE);
     }
     
     return (*my_func)();
       }
c-declare-end
)
;  from dlfcn.h ; see man dlopen
;
;       void * dlopen(const char *filename, int flag);
;       char * dlerror(void);
;       void * dlsym(void *handle, const char *symbol);
;       int    dlclose(void *handle);
;
; translated into Gambit-C FFI:
;
(define dlopen  (c-lambda (nonnull-char-string int32) (pointer void) "dlopen"))
(define dlerror (c-lambda () char-string "dlerror"))
(define dlsym   (c-lambda ((pointer void) nonnull-char-string) (pointer void) "dlsym"))
(define dlclose (c-lambda ((pointer void)) int32 "dlclose"))
;; hmm is there a defconstant in scheme that we could use for these C header constants?
;; for now generate a function of the same name to get us the constant int value we need.
(define RTLD_LAZY (c-lambda () int32 "___result = RTLD_LAZY;"))
; declare the type of the foreign function
(define call_print8 (c-lambda ((pointer void)) int32 "call_plugin_print8"))
(let* ((h  (dlopen "/home/jaten/dj/gamb/libex.so" (RTLD_LAZY)))
       (res (dlsym h "print8")))
       (if (null? res)
     (error "could not locate symbol 'print8' in the plugin library!"))
     
       (pretty-print (list "calling print8() gives: " (call_print8 h)))
       (pretty-print res)      
       (pretty-print h)
       (pretty-print (list "The value of the constant RTLD_LAZY is: " (RTLD_LAZY))))
;; output:
;;; $ ./dlopen
;
; In print8() : returning 8
;8
;#<void* #2 0x7fdd20c1868c>
;#<void* #3 0x22cd7b0>
;("The value of the constant RTLD_LAZY is: " 1)
;;;;;;;;;;;;;;;  file: Makefile   ;;;;;;;;;;;;
all:
    gsc -link dlopen.scm
    gcc -I/usr/local/Gambit-C/include -L/usr/local/Gambit-C/lib  dlopen.c  dlopen_.c  -lgambc -lm -lutil -ldl -o dlopen
    g++ -c libex.cpp      -fpic -o libex.o
    g++ -shared libex.o -o libex.so
    @echo "testing ./dlopen"
    ./dlopen
clean:
    rm -f dlopen dlopen_.c dlopen.c dlopen.o1 dlopen.o2 *~ *.o *.so