diff --git a/README.md b/README.md index c19dc14..c349e42 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ being portable by conforming to some specification. The new readme is a work in progress. -## Implementation table +## Implementation support tables ### Primitives 1 @@ -58,16 +58,59 @@ The new readme is a work in progress. | Stklos | X | X | | | Ypsilon | X | X | | +### Installation + +Either download the latest release from +[releases page](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 + +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." ## Documentation +### Types + +Types are given as symbols, for example 'int8 or 'pointer. + +- int8 +- uint8 +- int16 +- uint16 +- int32 +- uint32 +- int64 +- uint64 +- char +- unsigned-char +- short +- unsigned-short +- int +- unsigned-int +- long +- unsigned-long +- float +- double +- pointer +- callback + - Callback function + ### Primitives (**c-type-size** _type_) Returns the size of given C type. -(define-c-library) +(**define-c-library** _scheme-name_ _headers_ _object-name_ _options_) define-c-procedure define-c-callback c-bytevector? diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..78bc1ab --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.10.0 diff --git a/documentation/R7RS-PFFI.html b/documentation/R7RS-PFFI.html deleted file mode 100644 index 9c712d3..0000000 --- a/documentation/R7RS-PFFI.html +++ /dev/null @@ -1,797 +0,0 @@ - - - - - Portable Foreign Function Interface for R7RS -Documentation - 0.6.0 - - - -

Portable - Foreign Function Interface for R7RS

-

Portable foreign function interface for R7RS. It is portable - in the sense that it supports multiple implementations, as - opposed to being portable by conforming to some - specification.

-

Project

-

Issue - trackers

-

Maling - lists

-

Jenkins

-

Table of contents

- -
-

Goals

-

- -

Non goals

-

- -

Status

-

-

In alpha.

-

Current caveats

-

- -

Roadmap

-

For roadmap to 1.0.0 see issues

-

Feature mplementation - table

-

-

Primitives

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c-size-ofdefine-c-libraryc-bytevector?pffi-pointer-set!pffi-pointer-getdefine-c-procedurepffi-define-callback
ChibiXXXXXX
ChickenXXXXXXX
CycloneXXXXXX
GambitX
GaucheXXXXXX
Gerbil
GuileXXXXXXX
KawaXXXXXXX
Larceny
MoshXXXXXXX
RacketXXXXXXX
SaggittariusXXXXXXX
Skint
StklosXXX
tr7
YpsilonXXXXXXX
-

Built upon

-

-

These features are built upon the primitives and if - primitives are implemented and work, they should work too.

- -

Not started

-

- -

Other

-

- -

Documentation

-

-

Dependencies

-

-

Some implementations have extra dependencies/requirements - beyond just the library.

-

Chibi

-

-

Building depends on libffi.

-

Debian/Ubuntu/Mint install with:

-
apt install libffi-dev
-

Chicken

-

-

Chicken needs r7rs egg installed. Install it with:

-
chicken-install r7rs
-

Gauche

-

-

Building depends on libffi.

-

Debian/Ubuntu/Mint install with:

-
apt install libffi-dev
-

Racket

-

-

Needs racket-r7rs, - install with:

-
raco pkg install --auto r7rs
-

Kawa

-

-

Kawa Needs at least Java version 22 these flags before any - other arguments:

- -

If you are running kawa.jar with plain java then give same - arguments to java without the -J prefix.

-

Installation

-

-

Since the project is under active development is best to - clone it from git,

-

Project local

-

-

Linux

-

Assuming you - have a project and your libraries live in directory called snow - in it:

-
git clone https://git.sr.ht/~retropikzel/r7rs-pffi
-mkdir -p snow
-cp -r r7rs-pffi/retropikzel snow/
-cd snow/retropikzel/pffi
-make <SCHEME>
-

Windows

-

-

There is no build scripts yet for Windows, that said many - implementations work without compiling anything. If you run this - and it says “There is notching to build for SCHEME” then you - should be good to go.

-

System global

-

-

Still work in progress.

-

Reference

-

-

Types

-

-

Types are given as symbols, for example ’int8 or - ’pointer.

- -

Types

-

-

Environment variables

-

-

Setting environment variables like this on Windows works for - this library:

-
set "PFFI_LOAD_PATH=C:\Program Files (x86)/foo/bar"
-

PFFI_LOAD_PATH

-

-

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.

-

Procedures and macros

-

-

Some of these are procedures and some macros, it might also - change implementation to implementation.

-

pffi-init

-

-

pffi-init

-

Always call this first, on most implementation it does - nothing but some implementations might need initialisation - run.

-

c-size-of

-

-

c-size-of object -> number

-

Returns the size of the pffi-struct, pffi-enum or - pffi-type.

-

pffi-align-of

-

-

pffi-align-of type -> number

-

Returns the align of the type.

-

define-c-library

-

-

define-c-library headers shared-object-name - [options] -> object

-

Load given shared object automatically searching many - predefined paths.

-

Takes as argument a list of C headers, these are for the - compiler ones. And an shared-object name, used by the dynamic - FFI’s. The name of the shared object should not contain suffix - like .so or .dll. Nor should it contain any prefix like - “lib”.

-

Additional options argument can be provided, theys should be - a pair with a keyword. 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 ("."))))))
-

Notes

- -

make-c-null

-

-

make-c-null -> pointer

-

Returns a new NULL pointer.

-

c-null?

-

-

c-null? pointer -> boolean

-

Returns #t if given pointer is null pointer, #f - otherwise.

-

make-c-bytevector

-

-

make-c-bytevector size -> pointer

-

Returns newly allocated pointer of given size.

-

pffi-pointer-address

-

-

pffi-pointer-address pointer -> - pointer

-

Returns the address of given pointer inside a pointer. This - is used when passing pointers to pointers to foreign procedures. - This is similar to the c’s &. One important - difference is that after you have passed a pointer to - the procedure you must get value from it back to the pointer - which address you are passing. Example:

-
(define input-pointer (make-c-bytevector <needed size>))
-(define input-pointer-address (pffi-pointer-address input-pointer))
-(<foreign-procedure-that takes &pointer as argument> input-pointer-address)
-(set! input-pointer (pffi-pointer-get input-pointer-address 'pointer 0))
-

c-bytevector?

-

-

c-bytevector? object -> boolean

-

Returns #t if given object is pointer, #f otherwise.

-

c-free

-

-

c-free pointer

-

Frees given pointer.

-

pffi-pointer-set!

-

-

pffi-pointer-set! pointer type offset - value

-

Sets the value on a pointer on given offset. For example:

-
(define p (make-c-bytevector 128))
-(pffi-pointer-set! p 'int 64 100)
-

Would set the offset of 64, on pointer p to value 100.

-

pffi-pointer-get

-

-

pffi-pointer-get pointer type offset -> - object

-

Gets the value from a pointer on given offset. For - example:

-
(define p (make-c-bytevector 128))
-(pffi-pointer-set! p 'int 64 100)
-(pffi-pointer-get p 'int 64)
-> 100
-

string->c-bytevector

-

-

string->c-bytevector string -> - pointer

-

Makes pointer out of a given string.

-

c-bytevector->string

-

-

c-bytevector->sring pointer -> - string

-

Makes string out of a given pointer.

-

pffi-struct-make

-

-

pffi-struct-make c-type members . pointer - -> pffi-struct

-

Creates a new pffi-struct and allocates pointer for it. The - members argument is a list of member names and types. For - example:

-
(define color (pffi-struct-make 'color '((int8 . r) (int8 . g) (int8 . b) (int8 .a ))))
-(define test (pffi-struct-make "struct test" '((int8 . r) (int8 . g) (int8 . b) (int8 .a ))))
-

C-type argument can be symbol or a string.

-

pffi-struct-pointer

-

-

pffi-struct-pointer pffi-struct -> - pointer

-

Returns the pointer that holds the struct content. You need - to use this when passing a struct as a pointer to foreign - functions.

-
(define s (pffi-struct-make 'test '((int . r) (int . g) (int . b))))
-(pffi-struct-pointer s)
-

pffi-struct-offset-get

-

-

pffi-struct-offset-get member-name -> - number

-

Returns the offset of a struct member with given name.

-

pffi-struct-get

-

-

pffi-struct-get pffi-struct member-name - -> object

-

Returns the value of the givens struct member.

-

pffi-struct-set!

-

-

pffi-struct-set! pffi-struct member-name - value

-

Sets the value of the givens struct member. It is up to you - to make sure that the type of value is correct.

-

pffi-array-allocate

-

-

pffi-array-allocate type size

-

Allocates pointer array of given type and size.

-

pffi-array-pointer

-

-

pffi-array-pointer array

-

Returns the pointer of the array.

-

pffi-array?

-

-

pffi-array? object

-

Returns #t of given object is array, #f otherwise.

-

pffi-pointer->array

-

-

pffi-pointer->array pointer type size

-

Converts given pointer to an array of giben type and - size.

-

pffi-array-get

-

-

pffi-array-get array index

-

Returns the value of given index from given array.

-

pffi-array-set!

-

-

pffi-array-set! array index value

-

Sets the given value of given index in given array.

-

pffi-list->array

-

-

pffi-list->array type list

-

Converts given list into C array of given type.

-

pffi-array->list

-

-

pffi-array->list type list length

-

Converts given C array into list of given type and - length.

-

define-c-procedure

-

-

define-c-procedure scheme-name shared-object - c-name return-type argument-types

-

Defines a new foreign function to be used from Scheme code. - For example:

-
(cond-expand
-    (windows (define-c-library libc-stdlib '("stdlib.h") "ucrtbase" '("")))
-    (else (define-c-library libc-stdlib '("stdlib.h")  "c" '("" "6"))))
-(define-c-procedure c-puts libc-stdlib 'puts 'int '(pointer))
-(c-puts "Message brought to you by FFI!")
-

pffi-define-callback

-

-

pffi-define-callback scheme-name return-type - argument-types procedure

-

Defines a new Sceme function to be used as callback to C - code. For example:

-
; Load the shared library
-(cond-expand
-    (windows (define-c-library libc-stdlib '("stdlib.h") "ucrtbase" '()))
-    (else (define-c-library '("stdlib.h") "c" '("" "6"))))
-
-; Define C function that takes a callback
-(define-c-procedure qsort libc-stdlib 'qsort 'void '(pointer int int callback))
-
-; Define our callback
-(pffi-define-callback compare
-                      'int
-                      '(pointer pointer)
-                      (lambda (pointer-a pointer-b)
-                        (let ((a (pffi-pointer-get pointer-a 'int 0))
-                              (b (pffi-pointer-get pointer-b 'int 0)))
-                          (cond ((> a b) 1)
-                                ((= a b) 0)
-                                ((< a b) -1)))))
-
-; Create new array of ints to be sorted
-(define array (make-c-bytevector (* (c-size-of 'int) 3)))
-(pffi-pointer-set! array 'int (* (c-size-of 'int) 0) 3)
-(pffi-pointer-set! array 'int (* (c-size-of 'int) 1) 2)
-(pffi-pointer-set! array 'int (* (c-size-of 'int) 2) 1)
-
-(display array)
-(newline)
-;> (3 2 1)
-
-; Sort the array
-(qsort array 3 (c-size-of 'int) compare)
-
-(display array)
-(newline)
-;> (1 2 3)
-
- - diff --git a/documentation/R7RS-PFFI.pdf b/documentation/R7RS-PFFI.pdf deleted file mode 100644 index 2ac5fa0..0000000 Binary files a/documentation/R7RS-PFFI.pdf and /dev/null differ diff --git a/documentation/foreign-c.html b/documentation/foreign-c.html new file mode 100644 index 0000000..e307073 --- /dev/null +++ b/documentation/foreign-c.html @@ -0,0 +1,325 @@ + + + + + (foreign c) a portable foreign function interface for +R7RS - 0.10.0 + + + +

(foreign c)

+

(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.

+

The new readme is a work in progress.

+

Implementation table

+

Primitives 1

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
c-size-ofc-bytevector-u8-set!c-bytevector-u8-refdefine-c-libraryc-bytevector?define-c-procedure
ChibiXXXXXX
ChickenXXXXXX
GaucheXXXXXX
GuileXXXXXX
KawaXXXXXX
MoshXXXXXX
RacketXXXXXX
SaggittariusXXXXXX
StklosXXXXXX
YpsilonXXXXXX
+

Primitives 2

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
define-c-callback
Chibi
ChickenX
Gauche
GuileX
Kawa
MoshX
RacketX
SaggittariusX
Stklos
YpsilonX
+

Test files pass

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
primitives.scmaddressof.scmcallback.scm
ChibiXX
ChickenXXX
GaucheXX
GuileXXX
KawaXX
MoshXX
RacketX
SaggittariusXXX
StklosXX
YpsilonXX
+

Documentation

+

Types

+

Types are given as symbols, for example ’int8 or + ’pointer.

+ +

Primitives

+

(c-type-size type)

+

Returns the size of given C type.

+

(define-c-library scheme-name + headers object-name options) + define-c-procedure define-c-callback c-bytevector? + c-bytevector-u8-set! c-bytevector-u8-ref + c-bytevector-pointer-set! c-bytevector-pointer-ref

+

c-bytevector

+

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

+ + diff --git a/documentation/foreign-c.pdf b/documentation/foreign-c.pdf new file mode 100644 index 0000000..171e0a5 Binary files /dev/null and b/documentation/foreign-c.pdf differ