Next: , Previous: , Up: Top   [Index]


10 Interfacing with adapting foreign libraries

The core macro foreign-call, exported by the library (vicare), is expanded to the core language syntax foreign-call, which in turn is compiled to code invoking a C function from the operating system’s process image; the first argument to foreign-call is a string naming the C function.

Whenever the code:

(foreign-call "function_name" ?arg …)

is compiled, the C pointer referencing the entry point of the named function is retrieved with a C language call:

dlsym(RTLD_DEFAULT, "function_name");

so all the public functions from the running vicare executable are available; also available are all the functions from host’s shared libraries loaded with dlopen() using the flags RTLD_NOW | RTLD_GLOBAL.

This API for C language functions call is meant to be used to interface with functions specifically written to be called from Scheme code; examples are interface libraries installed by the Vicare extension packages like Vicare/CURL and Vicare/SQLite. This API cannot be used to directly call a generic C language function from, say, libz.so or libgmp.so.

It is possible to associate one or more host’s shared libraries to a FASL file, so that: whenever the FASL file is loaded, the shared library is loaded too and the functions required by foreign-call are available. This is especially useful to implement bindings to foreign libraries without relying on the FFI and making full use of garbage collection facilities and access to Scheme values’ memory representations.

A Vicare’s library might have the format:

(library (libname)
  (foreign-library ?foreign-library-id)
  (export . ?export-specs)
  (import . ?import-specs)
  . ?body)

and a Vicare’s top–level program might have the format:

(program (progname)
  (foreign-library ?foreign-library-id)
  (import . ?import-specs)
  . ?body)

the ?foreign-library-id form must be a string representing the identifier of a host’s shared object. There can be any number of foreign-library clauses, all before export for libraries and before import for programs.

The identifier is used to build the file name of a shared object; for example the identifier vicare-curl is used to build the following file names:

libvicare-curl.so

On Unix–like systems, including GNU+Linux.

libvicare-curl.dylib

On Darwin systems.

vicare-curl.dll

On Cygwin systems.

Whenever the library or program are expanded: the shared objects are immediately loaded using dlopen().

Whenever a library or program in binary form is written to a FASL file: an object field with header O is written to the beginning of the FASL file; such object will cause the shared object to be dynamically loaded whenever the FASL file is loaded.


Next: , Previous: , Up: Top   [Index]