QScheme provides a way to dynamically load dynamic libraries, to call functions of that library and to share variables with libraries.
(load-library name)-> <boolean>
Attempts to load la dynamic library. If the dynamic linkage succeeds and the
library contains a function named scm_init_name QScheme will
call this function to initialize the module. (See scm_init_regex
in regex.c for an example.)
To call a foreign function, you have to declare it first. As an example, here is the declaration of the system and printf functions from libc:
(define printf (make-extfunc *lib* :void "printf" '(:string . :any)))
May I ? 10 hello world It works...
>
You can pass strings as arguments to a foreign function. The string is passed to the function as is. If the size of the string should be adjusted, this may be done with the string- functions. For instance, this QScheme function lists the contents of a file using the stdio functions:
(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))))
QScheme can also access variables defined in dynamic libraries. (see load-library: 8.1).
(make-extern-variable libname type name)-> <external-variable>
Creates an external variable. libname is a string containing the path
to the dynamically loaded library. The library will be loaded on demand. The
type is a keyword as described in the table
|
The type of external strings is specified according to the string allocation scheme. We have to deal with the following cases:
When referring to a string stored in a static character buffer, you must 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.
Look at tstlib.c and tstlib.defs for an example that uses static and dynamic strings in a dynamic library.
Here is an example of how to share variable values between C and QScheme. In your C code, you have the following:
void test_func() {
printf("shared_var = %d\n", testvar_w);
}
(define shared-var (make-extern-variable *lib* :int "shared_var")
(define test-func (make-extfunc *lib* :void "test_func" '())
> (test-func)
shared_var = 100
> (display shared-var) (newline)
100
>
QScheme can create new Scheme object types at run-time.
(make-type name)-> <type-number>
Creates a new type of Scheme object. The number returned is the internal type
number.
(define-type <keyword> | <string> | <symbol>)-> #undefined
Creates a new type of Scheme object. This is just a wrapper around the make-type
function.
(internal-type-list) -> <list>
Returns a list of strings representing the know types.
(get-aux obj)-> <obj>
(set-aux! obj value)-> #undefined
(clear-aux! obj)-> #undefined
(null-aux? obj)-> <boolean>
These functions test and change the aux field of an object. The aux
field is large enough to store a pointer.
(define fopen
(make-extfunc "" :file "fopen" '(:string :string)))
(define fprintf
(make-extfunc "" :void "fprintf" '(:file :string . :any)))
(define _fclose (make-extfunc "" :void "fclose" '(:file)))
(define (fclose x)
(if (not (null-aux? x)) (_fclose x))
(clear-aux! x))
(add-type-finalizer
"file"
(lambda (x) (fclose x)))