next up previous contents
Next: 9. Running QScheme Up: QScheme Documentation Previous: 7. QScheme procedures   Contents

Subsections

8. Foreign function interface

QScheme provides a way to dynamically load dynamic library, to call functions of that library and to share variables with libraries.

8.1 Loading dynamic library

(load-library name)-> <boolean>
Dynamically try to load library. If dynamic linking is successful and the library contains a function like scm_init_name QScheme will call this function to initialize the module. (See scm_init_regex in regex.c for an example)

8.2 Calling a foreign function

To call a foreign function, you will first have to declare the foreign function for QScheme.

For example, this is the declaration of the system and printf functions from the libc:

(define system (make-extfunc *lib* :int "system" '(:string)))

(define printf (make-extfunc *lib* :void "printf" '(:string . :any)))

After that, you can use system and printf just like if it was a part of QScheme:

> (printf "May I ? %d %s\nIt works...\n" 10 "hello world") 

May I ? 10 hello world It works...

>

(make-extfunc libname ret-type ext-name arglist)-> <extfunc>
Create a new scheme object which can be use to call the foreign function ext-name

You can pass string as argument to a foreign function. The string is passed to the function. The size of the string will not be adjusted automatically. You have to do it with the string functions. For example this is a function to list the content of a file using the stdio functions:

(define (type file)

  (let ((fd) (buf) (bufsize 256))

    (set! fd (fopen file "r"))

    (if (not (null-pointer? fd))

        (begin

          (while 

           (not (null? 

                 (fgets

                  (set! buf (make-string bufsize #\space))

                  bufsize

                  fd)))

           (printf "%s\n" (string-chop buf)))

          (fclose fd))

        (printf "cannot open file %s" file))))

Note how we pass the buf to the fgets function and how we use it after.

8.3 Using a foreign variable

QScheme is able to access variable defined in dynamically loaded modules (see load-library).

(make-extern-variable libname type name)-> <external-variable>
Create an external variable. libname is a string containing the path to the dynamically loaded library. The library will be loaded on need. The type is a keyword as describe in table

Table 5: Type of external variables
Type C type Description
:char char a character
:short short a short integer
:long long a long integer
:float float a float number
:double double a double float number
:string char * a malloced string.
:string-buffer char * a pointer to a char buffer
:scheme SOBJ a pointer to a scheme object
     
     
     




5. The name is a string containing the name of the variable as defined in the module.

External string are a little complex because we have many cases:

When referring a dynamically allocated string, you need to use the :string type. Changing such a string from QScheme will first free memory then malloc a fresh copy of the string.

When referring a string stored in a static character buffer, you need to use the :string-buffer type. In this case the value is just copied in the buffer. Beware that no range check occurs. From QScheme, don't try to assign a string bigger than the static buffer size.

You should look at tstlib.c and tstlib.defs for an example of static and dynamic string.

This is a sample of how to share variable value between C and QScheme. In your C code, you have the following:

int shared_var;

 

void test_func() {

  printf("shared_var = %d\n", testvar_w);

}

You will have to declare the following from QScheme to share variable:

(define *lib* "./tstlib.so")

(define shared-var (make-extern-variable *lib* :int "shared_var")

(define test-func (make-extfunc *lib* :void "test_func" '())

Then you can get and set values like this:

> (set! shared-var 100)

> (test-func)

shared_var = 100

> (display shared-var) (newline)

100

>

Warning:
You must use define to bind a symbol to an external variable and set! to modify directly the value of the variable.


next up previous contents
Next: 9. Running QScheme Up: QScheme Documentation Previous: 7. QScheme procedures   Contents
Daniel Crettol
1999-09-17