On 13-Jun-09, at 5:15 AM, Aditya Godbole wrote:
Hi,
I'm trying to call functions written in scheme from C. I saw the server.scm and client.c as mentioned in docs, but I could not quite understand what it was doing. I also could not successfully link the application. Where can I find documentation for the ___setup function and the steps for compiling such a program?
TIA.
Aditya.
I've tried to come up with a simpler example than server.scm/client.c to explain how to write the C and Scheme code. The files are: "main-c- app.c" (the main program written in C) and "scmlib.scm" (the library of Scheme procedures you want to call from C). To keep things simple, scmlib.scm only defines the "hello" procedure which displays a message (a string passed from C to Scheme) and returns the length of the string.
The files are attached below and the top of main-c-app.c shows how to build the executable program (in a nutshell: use the -link option of gsc, and pass -D___LIBRARY and -lgambc to the C compiler when compiling the C code generated by gsc).
These are the fields of a ___setup_params_struct structure that can be set (note that calling ___setup_params_reset will assign reasonable default settings):
int version; /* must be equal to ___VERSION */ ___UCS_2STRING *argv; /* argv as UCS-2 strings */ unsigned long min_heap; /* min heap size */ unsigned long max_heap; /* max heap size */ int live_percent; /* live percentage (50 gives 50%) */ int standard_level; /* 5 gives R5RS */ int debug_settings; /* combination of ___DEBUG_SETTINGS_... values */ int file_settings; /* default file I/O settings (char- encoding, eol-encoding, ...) */ int terminal_settings; /* default terminal I/O settings */ int stdio_settings; /* default stdio I/O settings */ ___mod_or_lnk (*linker) ___P((___global_state_struct*),()); /* linker C function */
/* the following settings are not documented */ long (*gc_hook) ___P((long avail, long live),()); void (*display_error) ___P((char **msgs),()); void (*fatal_error) ___P((char **msgs),()); ___UCS_2STRING gambcdir; ___UCS_2STRING *gambcdir_map; ___UCS_2STRING remote_dbg_addr; ___UCS_2STRING rpc_server_addr;
Marc
----------------------------------------------------------------------- ;;; File: "scmlib.scm"
(c-define (hello str) (char-string) int "hello" "extern" (println "hello " str) (string-length str)) ----------------------------------------------------------------------- /* File: "main-c-app.c" */
/* % gsc -link scmlib.scm % gcc main-c-app.c -D___LIBRARY scmlib.c scmlib_.c -lgambc % ./a.out hello montreal returned 8 hello world returned 5 */
#define ___VERSION 404004 #include "gambit.h"
#define SCHEME_LIB_LINKER ____20_scmlib__
___BEGIN_C_LINKAGE extern ___mod_or_lnk SCHEME_LIB_LINKER (___global_state_struct*); ___END_C_LINKAGE
#include <stdio.h>
extern int hello( char *str ); /* defined in scmlib.scm */
int main( int argc, char **argv ) { ___setup_params_struct setup_params;
___setup_params_reset( &setup_params );
setup_params.version = ___VERSION; setup_params.linker = SCHEME_LIB_LINKER;
___setup( &setup_params ); /* setup Scheme library */
printf( "returned %d\n", hello( "montreal" ) ); printf( "returned %d\n", hello( "world" ) );
___cleanup(); /* cleanup Scheme library */
return 0; } -----------------------------------------------------------------------