foreign-c is a C foreign function interface (FFI) library for R7RS. It is portable in the sense that it supports multiple implementations, as opposed to being portable by conforming to some specification.
| c-size-of | c-bytevector-u8-set! | c-bytevector-u8-ref | define-c-library | c-bytevector? | define-c-procedure | |
|---|---|---|---|---|---|---|
| Chibi | X | X | X | X | X | X |
| Chicken | X | X | X | X | X | X |
| Gauche | X | X | X | X | X | X |
| Guile | X | X | X | X | X | X |
| Kawa | X | X | X | X | X | X |
| Mosh | X | X | X | X | X | X |
| Racket | X | X | X | X | X | X |
| Saggittarius | X | X | X | X | X | X |
| Stklos | X | X | X | X | X | X |
| Ypsilon | X | X | X | X | X | X |
| define-c-callback | |
|---|---|
| Chibi | |
| Chicken | X |
| Gauche | |
| Guile | X |
| Kawa | |
| Mosh | X |
| Racket | X |
| Saggittarius | X |
| Stklos | |
| Ypsilon | X |
| primitives.scm | addressof.scm | callback.scm | |
|---|---|---|---|
| Chibi | X | X | |
| Chicken | X | X | X |
| Gauche | X | X | |
| Guile | X | X | X |
| Kawa | X | X | |
| Mosh | X | X | |
| Racket | X | ||
| Saggittarius | X | X | X |
| Stklos | X | X | |
| Ypsilon | X | X |
Either download the latest release from https://git.sr.ht/~retropikzel/foreign-c/refs or git clone , preferably with a tag, and copy the “foreign” directory to your library directory.
As an example assuming you have a project and your libraries live in directory called snow in it:
git clone https://git.sr.ht/~retropikzel/foreign-c --branch LATEST_VERSION
mkdir -p snow
cp -r foreign-c/foreign snow/
make -C snow/foreign/c <SCHEME_IMPLEMENTATION_NAME>
With most implementations the make command does not compile anything. When that is the case it will say “Nothing to build on SCHEME_IMPLEMENTATION_NAME.”
Types are given as symbols, for example ’int8 or ’pointer.
(c-type-size type)
Returns the size of given C type.
(define-c-library scheme-name headers object-name options)
Takes a scheme-name to bind the library to, list of C headers as strings, shared-object name and options.
The C header strings should not contain “<” or “>”, they are added automatically.
The name of the shared object should not contain suffix like .so or .dll. Nor should it contain any prefix like “lib”.
The options are:
Example:
(cond-expand
(windows (define-c-library libc-stdlib
'("stdlib.h")
"ucrtbase"
'((additional-versions ("0" "6"))
(additiona-paths (".")))))
(else (define-c-library libc-stdlib
(list "stdlib.h")
"c"
'((additional-versions ("0" "6"))
(additiona-paths ("."))))))
make-c-bytevector make-c-null c-null? c-free native-endianness c-bytevector-s8-set! c-bytevector-s8-ref c-bytevector-s16-set! c-bytevector-s16-ref c-bytevector-s16-native-set! c-bytevector-s16-native-ref c-bytevector-u16-set! c-bytevector-u16-ref c-bytevector-u16-native-set! c-bytevector-u16-native-ref c-bytevector-s32-set! c-bytevector-s32-ref c-bytevector-s32-native-set! c-bytevector-s32-native-ref c-bytevector-u32-set! c-bytevector-u32-ref c-bytevector-u32-native-set! c-bytevector-u32-native-ref c-bytevector-s64-set! c-bytevector-s64-ref c-bytevector-s64-native-set! c-bytevector-s64-native-ref c-bytevector-u64-set! c-bytevector-u64-ref c-bytevector-u64-native-set! c-bytevector-u64-native-ref c-bytevector-sint-set! c-bytevector-sint-ref c-bytevector-uint-set! c-bytevector-uint-ref c-bytevector-ieee-single-set! c-bytevector-ieee-single-native-set! c-bytevector-ieee-single-ref c-bytevector-ieee-single-native-ref c-bytevector-ieee-double-set! c-bytevector-ieee-double-native-set! c-bytevector-ieee-double-ref c-bytevector-ieee-double-native-ref bytevector->c-bytevector c-bytevector->bytevector call-with-address-of
string->c-utf8 c-utf8->string
Setting environment variables like this on Windows works for this library:
set "PFFI_LOAD_PATH=C:\Program Files (x86)/foo/bar"
To add more paths to where pffi looks for libraries set PFFI_LOAD_PATH to paths separated by ; on windows, and : on other operating systems.