(foreign c) is a C foreign function interface (FFI) library for R6RS and R7RS Schemes
Repository
Supported implementations
R6RS is supported trough akku.
- Chez => 10.0.0
- R6RS
- Chibi > 0.11
- R7RS
- Depends on libffi
- Chicken >= 6.0.0
- R7RS
- Ikarus >= 0.0.4-rc1+
- R6RS
- Ironscheme
- R6RS
- Kawa >= 3.11 and Java >= 24
- R7RS
- Needs arguments to enable FFI
- -J--add-exports=java.base/jdk.internal.foreign.abi=ALL-UNNAMED
- -J--add-exports=java.base/jdk.internal.foreign.layout=ALL-UNNAMED
- -J--add-exports=java.base/jdk.internal.foreign=ALL-UNNAMED
- -J--enable-native-access=ALL-UNNAMED
- All needed arguments on one line for copy pasting
- -J--add-exports=java.base/jdk.internal.foreign.abi=ALL-UNNAMED -J--add-exports=java.base/jdk.internal.foreign.layout=ALL-UNNAMED -J--add-exports=java.base/jdk.internal.foreign=ALL-UNNAMED -J--enable-native-access=ALL-UNNAMED
- So that snow-chibi installed library is found
- -Dkawa.import.path=/usr/local/share/kawa/lib/*.sld
- Mosh
- R7RS
- Racket >= 8.16 [cs]
- R7RS
- Sagittarius >= 0.9.13
- R6RS
- R7RS
- STklos >= 26.0
- R7RS
- Ypsilon >= 2.08
- R7RS
- Do not cond-expand inside the arguments, that might lead to problems on some
implementations.
- Do not store member names or types in variables, that might lead to problems
on some implementations.
- Pass the members using quote
- As '(...) and not (list ...)
(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 or #f and options. If shared-object name
is given as #f then platforms C library is used.
The C header strings should not contain "<" or ">", they are added
automatically. Pass them using ' and not (list ...).
The name of the shared object should not contain suffix like .so or .dll.
Nor should it contain any prefix like "lib".
Options:
- additional-versions
- Search for additional versions of shared object, given shared object "c"
and additional versions "6" "7" on linux the files "libc", "libc.6",
"libc.7" are searched for.
- Can be either numbers or strings
- additional-paths
- Give additional paths to search shared objects from
Example:
(define-c-library libc '("stdio.h") #f '())
(define-c-library libcurl
'("curl/curl.h")
"curl"
'((additional-versions ("" "0" "6"))
(additional-paths ("."))))
(define-c-procedure scheme-name shared-object c-name return-type argument-types)
Takes a scheme-name to bind the C procedure to, shared-object where the function
is looked from, c-name of the function as symbol, return-type and argument-types.
Defines a new foreign function to be used from Scheme code.
Example:
(define-c-library libc '("stdlib.h") #f '())
(define-c-procedure c-puts libc 'puts 'int '(pointer))
(c-puts "Message brought to you by foreign-c!")
(foreign-c-internal-make-c-bytevector pointer)
Internal procedure, do not use.
Setting environment variables like this on Windows works for this library:
set "FOREIGN_C_LOAD_PATH=C:Program Files (x86)/foo/bar"
To add more paths to where foreign c looks for libraries set
FOREIGN_C_LOAD_PATH to paths separated by ; on windows, and : on other
operating systems.
(define-c-callback scheme-name return-type argument-types procedure)
Takes scheme-name to bind the Scheme procedure to, return-type,
argument-types and procedure as in place lambda.
Defines a new Sceme function to be used as callback to C code.
This procedure can be used inside the callback to make c-bytevector out of
C pointer.
Call with address of (C &)
(call-with-address-of cbv thunk)
Calls thunk with address c-bytevector of c-bytevector.
Since the support for calling C functions taking pointer address arguments,
ones prefixed with & in C, varies, some additional ceremony is needed on
the Scheme side.
Example:
Calling from C:
//void func(int** i);
func(&i);
Calling from Scheme:
(define cbv (make-bytevector (c-type-size 'int)))
(call-with-address-of
cbv
(lambda (address)
(func address)))
; Use cbv here
The passed c-bytevector, in example named cbv, should only be used **after**
call to call-with-addres-of ends.
(make-c-bytevector size . byte)
Returns a newly allocated c-bytevector of size bytes.
If the fill argument is missing, the initial contents of the
returned c-bytevector are unspecified.
If the fill argument is present, it's value must confine to C u8 values,
it specifies the initial value for the bytes of the c-bytevector.
If allocation fails, error is signaled.
Example:
(make-c-bytevector 128)
(make-c-bytevector 128 0)
Returns a newly allocated c-bytevector containing its arguments.
Example:
(c-bytevector 0 0 0 0)
Returns #t if obj is c-bytevector, otherwise returns #f.
(c-bytevector-free cbv ...)
Frees given c-bytevectors from memory.
Returns a null c-bytevector.
Returns #t if obj is a null c-bytevector, otherwise returns #f.
(c-bytevector-set! cbv type offset/member value)
Set value of given type on offset on bytevector bv. Offset is counted as
bytes for regular types.
When type is c-array-type offset is multiplied by the size of arrays type.
When type is c-struct-type type instead of offset give member name.
(c-bytevector-ref cbv type offset/member)
Get value of given type on offset on bytevector bv. Offset is counted as
bytes for regular types.
When type is c-array-type offset is multiplied by the size of arrays type.
When type is c-struct-type type instead of offset give member name.
(bytevector->c-bytevector bv)
Returns a newly allocated c-bytevector of the bytes of bytevector.
(c-bytevector->bytevector cbv size)
Returns a newly allocated bytevector of the bytes of c-bytevector.
(c-bytevector->string cbv)
Returns a newly allocated string whose character sequence is
encoded by the given c-bytevector. If c-bytevector is null empty string is
returned.
(string->c-bytevector str)
Returns a newly allocated (unless empty) c-bytevector that contains the
UTF-8 encoding of the given string.
(with-string->c-bytevector str thunk)
Calls thunk with newly allocated c-bytevector that contains the UTF-8 encoding
of the given string and frees it after thunk finishes.
(c-bytevector->integer cbv . offset)
Returns the address of the bytevector as integer. If offset is given it is
added to the the returned integer. Offset must be an integer.
(integer->c-bytevector address)
Returns the bytevector in the integer address.
Null byte (0) you can use in strings.
Returns #t if given type is C integer type, otherwise returns #f
Example:
(c-integer-type? 'i8)
> #t
Returns #t if given type is C char type, otherwise returns #f
Example:
(c-char-type? 'char)
> #t
Returns #t if given type is C float type, otherwise returns #f
Example:
(c-float-type? 'float)
> #t
Returns #t if given type is C double type, otherwise returns #f
Example:
(c-double-type? 'double)
> #t
Returns #t if given type is C signed type, otherwise returns #f
Example:
(c-signed-type? 'i8)
> #t
(c-signed-type? 'u8)
> #f
Returns #t if given type is C pointer type, otherwise returns #f
Example:
(c-pointer-type? 'pointer)
> #t
Returns the size of given type.
Example:
(c-type-size 'i8)
> 1
(define-c-array-type items 'i8)
(c-type-size items)
> 1
(define-c-array-type color '((r u8) (g u8) (b u8)))
(c-type-size color)
> 3
Adds given types together and returns the result.
Example:
(c-type-size+ 'u8 'u8)
> 2
Subtracts given types and returns the result.
Example:
(c-type-size- 'int 'u8)
> 3
Divides given type with n and retursn the result.
Example:
(c-type-size/ 'int 2)
> 2
Multiplies given type with n and returns the result.
Example:
(c-type-size* 'int 10)
> 40
Returns the align of given type.
Example:
(c-type-align 'int)
> 4
Adds given aligns together and returns the result.
Example:
(c-type-align+ 'u8 'u8)
> 2
Subtracts given aligns and returns the result.
Example:
(c-type-align- 'int 'u8)
> 3
Multiples given align with n and returns the result.
Example:
(c-type-align* 'int 100)
> 400
Divides given align with n and retursn the result.
Example:
(c-type-align/ 'int 2)
> 2
Returns #t if given type is C array type, otherwise returns #f
Example:
(define-c-array-type items 'i8)
(c-integer-type? items)
> #t
(define-c-array-type name type)
Creates a new C array type that can be used when accessing c-bytevectors.
name is the name of the type and type is the type of items.
Example:
(define-c-array-type i8-array 'i8)
(define ar1 (make-c-bytevector (* (c-type-size i8-array) 10)))
(c-bytevector-set! ar1 i8-array 5 25) ; Set the 5th item of array to 25
(write (c-bytevector-ref ar1 i8-array 5))
> 25
Returns #t if given type is C array type, otherwise returns #f
Example:
(define-c-struct-type color '((r u8) (g u8) (b u8)))
(c-struct-type? color)
> #t
(define-c-struct-type name members)
Creates a new C struct type that can be used when accessing c-bytevectors.
name is the name of the type and members is a list of member names and types.
Example:
(define-c-struct-type color '((r i8) (g i8) (b i8) (a i8)))
(define green (make-c-bytevector (c-type-size color)))
(c-bytevector-set! green color 'r 1)
(c-bytevector-set! green color 'g 2)
(c-bytevector-set! green color 'b 3)
(c-bytevector-set! green color 'a 4)
(display (c-bytevector-ref green color 'g))
> 2
Creates an association list from given struct type and c-bytevector.