Git commit renaming and restructuring the library
This commit is contained in:
parent
04d4e43b04
commit
8d012a5ba2
|
|
@ -45,3 +45,4 @@ tests/retropikzel
|
||||||
testfile.test
|
testfile.test
|
||||||
tests/testfile.test
|
tests/testfile.test
|
||||||
snow
|
snow
|
||||||
|
foreign/c/lib
|
||||||
|
|
|
||||||
54
Makefile
54
Makefile
|
|
@ -9,64 +9,64 @@ docs:
|
||||||
mkdir -p documentation
|
mkdir -p documentation
|
||||||
pandoc --standalone \
|
pandoc --standalone \
|
||||||
--template templates/documentation.html README.md \
|
--template templates/documentation.html README.md \
|
||||||
> documentation/R7RS-PFFI.html
|
> documentation/foreign-c.html
|
||||||
pandoc -t html5 \
|
pandoc -t html5 \
|
||||||
--pdf-engine=weasyprint \
|
--pdf-engine=weasyprint \
|
||||||
--css templates/css/pdf-documentation.css \
|
--css templates/css/pdf-documentation.css \
|
||||||
-o documentation/R7RS-PFFI.pdf \
|
-o documentation/foreign-c.pdf \
|
||||||
README.md
|
README.md
|
||||||
|
|
||||||
chibi:
|
chibi:
|
||||||
make -C retropikzel/pffi chibi
|
make -C foreign/c chibi
|
||||||
|
|
||||||
chicken:
|
chicken:
|
||||||
make -C retropikzel/pffi chicken
|
make -C foreign/c chicken
|
||||||
|
|
||||||
cyclone:
|
cyclone:
|
||||||
make -C retropikzel/pffi cyclone
|
make -C foreign/c cyclone
|
||||||
|
|
||||||
gambit:
|
gambit:
|
||||||
make -C retropikzel/pffi gambit
|
make -C foreign/c gambit
|
||||||
|
|
||||||
gauche:
|
gauche:
|
||||||
make -C retropikzel/pffi gauche
|
make -C foreign/c gauche
|
||||||
|
|
||||||
gerbil:
|
gerbil:
|
||||||
make -C retropikzel/pffi gerbil
|
make -C foreign/c gerbil
|
||||||
|
|
||||||
guile:
|
guile:
|
||||||
make -C retropikzel/pffi guile
|
make -C foreign/c guile
|
||||||
|
|
||||||
kawa:
|
kawa:
|
||||||
make -C retropikzel/pffi kawa
|
make -C foreign/c kawa
|
||||||
|
|
||||||
larceny:
|
larceny:
|
||||||
make -C retropikzel/pffi larceny
|
make -C foreign/c larceny
|
||||||
|
|
||||||
mosh:
|
mosh:
|
||||||
make -C retropikzel/pffi mosh
|
make -C foreign/c mosh
|
||||||
|
|
||||||
racket:
|
racket:
|
||||||
make -C retropikzel/pffi racket
|
make -C foreign/c racket
|
||||||
|
|
||||||
sagittarius:
|
sagittarius:
|
||||||
make -C retropikzel/pffi sagittarius
|
make -C foreign/c sagittarius
|
||||||
|
|
||||||
skint:
|
skint:
|
||||||
make -C retropikzel/pffi skint
|
make -C foreign/c skint
|
||||||
|
|
||||||
stklos:
|
stklos:
|
||||||
make -C retropikzel/pffi stklos
|
make -C foreign/c stklos
|
||||||
|
|
||||||
tr7:
|
tr7:
|
||||||
make -C retropikzel/pffi tr7
|
make -C foreign/c tr7
|
||||||
|
|
||||||
ypsilon:
|
ypsilon:
|
||||||
make -C retropikzel/pffi tr7
|
make -C foreign/c tr7
|
||||||
|
|
||||||
test-compile-r7rs: tmp/test/libtest.o tmp/test/libtest.so tmp/test/libtest.a
|
test-compile-r7rs: tmp/test/libtest.o tmp/test/libtest.so tmp/test/libtest.a
|
||||||
make ${COMPILE_R7RS}
|
make ${COMPILE_R7RS}
|
||||||
cp -r retropikzel tmp/test/
|
cp -r foreign tmp/test/
|
||||||
cp tests/*.scm tmp/test/
|
cp tests/*.scm tmp/test/
|
||||||
cp tests/c-include/libtest.h tmp/test/
|
cp tests/c-include/libtest.h tmp/test/
|
||||||
cd tmp/test && \
|
cd tmp/test && \
|
||||||
|
|
@ -93,29 +93,13 @@ tmp/test/libtest.a: tmp/test/libtest.o tests/c-src/libtest.c
|
||||||
ar rcs tmp/test/libtest.a tmp/test/libtest.o
|
ar rcs tmp/test/libtest.a tmp/test/libtest.o
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -rf retropikzel/pffi/pffi.c
|
|
||||||
@rm -rf retropikzel/pffi/*.o*
|
|
||||||
@rm -rf retropikzel/pffi/*.so
|
|
||||||
@rm -rf retropikzel/pffi/*.meta
|
|
||||||
@rm -rf retropikzel/pffi/retropikzel.*
|
|
||||||
@rm -rf retropikzel/pffi/compiled
|
|
||||||
@rm -rf retropikzel.*
|
|
||||||
find . -name "*.meta" -delete
|
find . -name "*.meta" -delete
|
||||||
@rm -rf test/pffi-define
|
|
||||||
@rm -rf test/*gambit*
|
|
||||||
find . -name "*.link" -delete
|
find . -name "*.link" -delete
|
||||||
find . -name "*.o" -delete
|
find . -name "*.o" -delete
|
||||||
find . -name "*.o[1-9]" -delete
|
find . -name "*.o[1-9]" -delete
|
||||||
find . -name "*.so" -delete
|
find . -name "*.so" -delete
|
||||||
find . -name "*.a" -delete
|
find . -name "*.a" -delete
|
||||||
find . -name "*.class" -delete
|
find . -name "*.class" -delete
|
||||||
@rm -rf test
|
|
||||||
find . -name "core.1" -delete
|
find . -name "core.1" -delete
|
||||||
find . -name "*@gambit*" -delete
|
find . -name "*@gambit*" -delete
|
||||||
rm -rf retropikzel/pffi.c
|
|
||||||
rm -rf tests/compliance.c*
|
|
||||||
rm -rf tests/compliance.o
|
|
||||||
rm -rf tests/compliance.so
|
|
||||||
rm -rf tests/compliance
|
|
||||||
rm -rf tests/retropikzel.*.import.scm
|
|
||||||
rm -rf tmp
|
rm -rf tmp
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,654 @@
|
||||||
|
---
|
||||||
|
title: Portable Foreign Function Interface for R7RS Documentation
|
||||||
|
version: 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](https://todo.sr.ht/~retropikzel/r7rs-pffi)
|
||||||
|
|
||||||
|
[Issue trackers](https://sr.ht/~retropikzel/r7rs-pffi/trackers)
|
||||||
|
|
||||||
|
[Maling lists](https://sr.ht/~retropikzel/r7rs-pffi/lists)
|
||||||
|
|
||||||
|
[Jenkins](https://jenkins.scheme.org/job/r7rs_pffi/job/r7rs-pffi/)
|
||||||
|
|
||||||
|
## Table of contents
|
||||||
|
|
||||||
|
<nav>
|
||||||
|
|
||||||
|
- [Goals](#goals)
|
||||||
|
- [Non Goals](#non-goals)
|
||||||
|
- [Status](#status)
|
||||||
|
- [Current caveats](#current-caveats)
|
||||||
|
- [Roadmap](#roadmap)
|
||||||
|
- [Feature implementation table](#feature-implementation-table)
|
||||||
|
- [Primitives](#feature-implementation-table-primitives)
|
||||||
|
- [Built upon](#feature-implementation-table-built-upon)
|
||||||
|
- [Documentation](#documentation)
|
||||||
|
- [Dependencies](#dependencies)
|
||||||
|
- [Chibi](#dependencies-chibi)
|
||||||
|
- [Chicken](#dependencies-chicken)
|
||||||
|
- [Gauche](#dependencies-gauche)
|
||||||
|
- [Racket](#dependencies-racket)
|
||||||
|
- [Kawa](#dependencies-kawa)
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [Project local](#installation-project-local)
|
||||||
|
- [Linux](#installation-project-local-linux)
|
||||||
|
- [Windows](#installation-project-local-windows)
|
||||||
|
- [System global](#installation-system-global)
|
||||||
|
- [Reference](#reference)
|
||||||
|
- [Types](#types)
|
||||||
|
- [Environment variables](#environment-variables)
|
||||||
|
- [PFFI\_LOAD\_PATH](#environment-variables-pffi-load-path)
|
||||||
|
- [Procedures and macros](#procedures-and-macros)
|
||||||
|
- [pffi-init](#pffi-init)
|
||||||
|
- [c-size-of](#c-size-of)
|
||||||
|
- [pffi-align-of](#pffi-align-of)
|
||||||
|
- [define-c-library](#define-c-library)
|
||||||
|
- [make-c-null](#make-c-null)
|
||||||
|
- [c-null?](#is-c-null)
|
||||||
|
- [make-c-bytevector ](#make-c-bytevector )
|
||||||
|
- [pffi-pointer-address](#pffi-pointer-address)
|
||||||
|
- [c-bytevector?](#is-c-bytevector)
|
||||||
|
- [c-free](#c-free)
|
||||||
|
- [pffi-pointer-set!](#pffi-pointer-set!)
|
||||||
|
- [pffi-pointer-get](#pffi-pointer-get)
|
||||||
|
- [utf8->c-bytevector](#utf8-into-c-bytevector)
|
||||||
|
- [c-bytevector->sring](#c-bytevector-into-string)
|
||||||
|
- [pffi-struct-make](#pffi-struct-make)
|
||||||
|
- [pffi-struct-pointer](#pffi-struct-pointer)
|
||||||
|
- [pffi-struct-offset-get](#pffi-struct-offset-get)
|
||||||
|
- [pffi-struct-get](#pffi-struct-get)
|
||||||
|
- [pffi-struct-set!](#pffi-struct-set!)
|
||||||
|
- [pffi-array-allocate](#pffi-array-allocate)
|
||||||
|
- [pffi-array-pointer](#pffi-array-pointer)
|
||||||
|
- [pffi-array?](#pffi-array)
|
||||||
|
- [pffi-pointer->array](#pffi-pointer->array)
|
||||||
|
- [pffi-array-get](#pffi-array-get)
|
||||||
|
- [pffi-array-set!](#pffi-array-set!)
|
||||||
|
- [pffi-list->array](#pffi-list->array)
|
||||||
|
- [pffi-array->list](#pffi-array->list)
|
||||||
|
- [define-c-procedure](#define-c-procedure)
|
||||||
|
- [pffi-define-callback](#pffi-define-callback)
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
<a name="goals"></a>
|
||||||
|
|
||||||
|
- Support only R7RS implementations
|
||||||
|
- Same interface on all implementations
|
||||||
|
- Some things that are procedures on one implementation are macros on other,
|
||||||
|
but they must behave the same
|
||||||
|
- Stability and being boring after 1.0.0 is reached
|
||||||
|
|
||||||
|
## Non goals
|
||||||
|
<a name="non-goals"></a>
|
||||||
|
|
||||||
|
- Compiling of used library C code at any point
|
||||||
|
- That is no stubs, no C code generated by the library and so on
|
||||||
|
- The pffi library itself may require compilation on installation
|
||||||
|
|
||||||
|
## Status
|
||||||
|
<a name="status"></a>
|
||||||
|
|
||||||
|
In alpha.
|
||||||
|
|
||||||
|
### Current caveats
|
||||||
|
<a name="current-caveats"></a>
|
||||||
|
|
||||||
|
- No way to pass structs by value
|
||||||
|
- Most implementations are missing callback support
|
||||||
|
- Always pass arguments to pffi functions/macros as '(1 2 3) and not (list 1 2 3)
|
||||||
|
- Always pass pffi-define-callback procedure as lambda in place
|
||||||
|
- No support for variadic function arguments
|
||||||
|
- Can be partially worked around by defining multiple versions of same
|
||||||
|
function with different number of arguments
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
For roadmap to 1.0.0 see [issues](https://todo.sr.ht/~retropikzel/r7rs-pffi?search=status%3Aopen%20label%3A%221.0.0%22)
|
||||||
|
|
||||||
|
## Feature mplementation table
|
||||||
|
<a name="feature-implementation-table"></a>
|
||||||
|
|
||||||
|
## Primitives
|
||||||
|
<a name="feature-implementation-table-primitives"></a>
|
||||||
|
|
||||||
|
| | c-size-of | define-c-library | c-bytevector? | pffi-pointer-set! | pffi-pointer-get | define-c-procedure | pffi-define-callback |
|
||||||
|
|--------------|:------------:|:-------------------:|:-------------:|:-----------------:|:----------------:|:-------------------:|:--------------------:|
|
||||||
|
| Chibi | X | X | X | X | X | X | |
|
||||||
|
| Chicken | X | X | X | X | X | X | X |
|
||||||
|
| Cyclone | X | X | X | X | X | X | |
|
||||||
|
| Gambit | X | | | | | | |
|
||||||
|
| Gauche | X | X | X | X | X | X | |
|
||||||
|
| Gerbil | | | | | | | |
|
||||||
|
| Guile | X | X | X | X | X | X | X |
|
||||||
|
| Kawa | X | X | X | X | X | X | X |
|
||||||
|
| Larceny | | | | | | | |
|
||||||
|
| Mosh | X | X | X | X | X | X | X |
|
||||||
|
| Racket | X | X | X | X | X | X | X |
|
||||||
|
| Saggittarius | X | X | X | X | X | X | X |
|
||||||
|
| Skint | | | | | | | |
|
||||||
|
| Stklos | X | X | X | | | | |
|
||||||
|
| tr7 | | | | | | | |
|
||||||
|
| Ypsilon | X | X | X | X | X | X | X |
|
||||||
|
|
||||||
|
## Built upon
|
||||||
|
<a name="feature-implementation-table-built-upon"></a>
|
||||||
|
|
||||||
|
These features are built upon the primitives and if primitives are implemented
|
||||||
|
and work, they should work too.
|
||||||
|
|
||||||
|
- make-c-bytevector
|
||||||
|
- make-c-null
|
||||||
|
- c-null?
|
||||||
|
- pffi-pointer-address
|
||||||
|
- c-free
|
||||||
|
- pffi-pointer-\>string
|
||||||
|
- pffi-string-\>pointer
|
||||||
|
- pffi-struct-make
|
||||||
|
- pffi-struct-pointer
|
||||||
|
- pffi-struct-offset-get
|
||||||
|
- pffi-struct-get
|
||||||
|
- pffi-struct-set!
|
||||||
|
- pffi-array-allocate
|
||||||
|
- pffi-array?
|
||||||
|
- pffi-pointer-\>array
|
||||||
|
- pffi-array-get
|
||||||
|
- pffi-array-set!
|
||||||
|
- pffi-list-\>array
|
||||||
|
- pffi-array-\>list
|
||||||
|
|
||||||
|
### Not started
|
||||||
|
<a name="not-started"></a>
|
||||||
|
|
||||||
|
- [LIPS](https://lips.js.org/)
|
||||||
|
- Will work on nodejs by using some C FFI library from npm
|
||||||
|
- Javascript side needs design
|
||||||
|
- [Biwascheme](https://www.biwascheme.org/)
|
||||||
|
- Will work on nodejs by using some C FFI library from npm
|
||||||
|
- Javascript side needs design
|
||||||
|
- [MIT-Scheme](https://www.gnu.org/software/mit-scheme/)
|
||||||
|
- Need to study the implementation more
|
||||||
|
- [Airship](https://gitlab.com/mbabich/airship-scheme)
|
||||||
|
- Need to study the implementation more
|
||||||
|
- [Other gambit targets](https://gambitscheme.org/)
|
||||||
|
- Gambit compiles to different targets other than C too, for example Javascript. It would be cool
|
||||||
|
and interesting to see if this FFI could also support some of those
|
||||||
|
- When LIPS and Biwascheme Javascript side is done then Gambit should be done too
|
||||||
|
- [s48-r7rs](https://codeberg.org/prescheme/s48-r7rs)
|
||||||
|
- Need to study the implementation more
|
||||||
|
- [prescheme](https://codeberg.org/prescheme/prescheme)
|
||||||
|
- Need to study the implementation more
|
||||||
|
|
||||||
|
### Other
|
||||||
|
<a name="other"></a>
|
||||||
|
|
||||||
|
- [s7](https://scheme.fail://ccrma.stanford.edu/software/snd/snd/s7.html)
|
||||||
|
- Propably does not need FFI as it is embeddable only
|
||||||
|
- [Loko](https://scheme.fail/)
|
||||||
|
- Desires no C interop, I can respect that
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
<a name="documentation"></a>
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
<a name="dependencies"></a>
|
||||||
|
|
||||||
|
Some implementations have extra dependencies/requirements beyond just the
|
||||||
|
library.
|
||||||
|
|
||||||
|
#### Chibi
|
||||||
|
<a name="dependencies-chibi"></a>
|
||||||
|
|
||||||
|
Building depends on libffi.
|
||||||
|
|
||||||
|
Debian/Ubuntu/Mint install with:
|
||||||
|
|
||||||
|
apt install libffi-dev
|
||||||
|
|
||||||
|
#### Chicken
|
||||||
|
<a name="dependencies-chicken"></a>
|
||||||
|
|
||||||
|
Chicken needs r7rs egg installed. Install it with:
|
||||||
|
|
||||||
|
chicken-install r7rs
|
||||||
|
|
||||||
|
#### Gauche
|
||||||
|
<a name="dependencies-gauche"></a>
|
||||||
|
|
||||||
|
Building depends on libffi.
|
||||||
|
|
||||||
|
Debian/Ubuntu/Mint install with:
|
||||||
|
|
||||||
|
apt install libffi-dev
|
||||||
|
|
||||||
|
#### Racket
|
||||||
|
<a name="dependencies-racket"></a>
|
||||||
|
|
||||||
|
Needs [racket-r7rs](https://github.com/lexi-lambda/racket-r7rs), install with:
|
||||||
|
|
||||||
|
raco pkg install --auto r7rs
|
||||||
|
|
||||||
|
#### Kawa
|
||||||
|
<a name="dependencies-kawa"></a>
|
||||||
|
|
||||||
|
Kawa Needs at least Java version 22 these flags before any other arguments:
|
||||||
|
|
||||||
|
- \-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
|
||||||
|
|
||||||
|
If you are running kawa.jar with plain java then give same arguments to java
|
||||||
|
without the -J prefix.
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
<a name="installation"></a>
|
||||||
|
|
||||||
|
Since the project is under active development is best to clone it from git,
|
||||||
|
|
||||||
|
### Project local
|
||||||
|
<a name="installation-project-local"></a>
|
||||||
|
|
||||||
|
#### Linux
|
||||||
|
<a name="installation-project-local-linux"></a>
|
||||||
|
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
|
||||||
|
<a name="installation-project-local-windows"></a>
|
||||||
|
|
||||||
|
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
|
||||||
|
<a name="installation-system-global"></a>
|
||||||
|
|
||||||
|
Still work in progress.
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
<a name="reference"></a>
|
||||||
|
|
||||||
|
### Types
|
||||||
|
<a name="types"></a>
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
### Types
|
||||||
|
<a name="types"></a>
|
||||||
|
|
||||||
|
### Environment variables
|
||||||
|
<a name="environment-variables"></a>
|
||||||
|
|
||||||
|
Setting environment variables like this on Windows works for this library:
|
||||||
|
|
||||||
|
set "PFFI_LOAD_PATH=C:\Program Files (x86)/foo/bar"
|
||||||
|
|
||||||
|
#### PFFI\_LOAD\_PATH
|
||||||
|
<a name="environment-variables-pffi-load-path"></a>
|
||||||
|
|
||||||
|
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
|
||||||
|
<a name="procedures-and-macros"></a>
|
||||||
|
|
||||||
|
Some of these are procedures and some macros, it might also change implementation to implementation.
|
||||||
|
|
||||||
|
#### pffi-init
|
||||||
|
<a name="pffi-init"></a>
|
||||||
|
|
||||||
|
**pffi-init**
|
||||||
|
|
||||||
|
Always call this first, on most implementation it does nothing but some implementations might need
|
||||||
|
initialisation run.
|
||||||
|
|
||||||
|
#### c-size-of
|
||||||
|
<a name="c-size-of"></a>
|
||||||
|
|
||||||
|
**c-size-of** object -> number
|
||||||
|
|
||||||
|
Returns the size of the pffi-struct, pffi-enum or pffi-type.
|
||||||
|
|
||||||
|
#### pffi-align-of
|
||||||
|
<a name="pffi-align-of"></a>
|
||||||
|
|
||||||
|
**pffi-align-of** type -> number
|
||||||
|
|
||||||
|
Returns the align of the type.
|
||||||
|
|
||||||
|
#### define-c-library
|
||||||
|
<a name="define-c-library"></a>
|
||||||
|
|
||||||
|
**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:
|
||||||
|
|
||||||
|
- 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 for
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
- Do not cond-expand inside the arguments, that might lead to problems on some
|
||||||
|
implementations.
|
||||||
|
- Do not store options in variables, that might lead to problems on some
|
||||||
|
implementations.
|
||||||
|
- Do pass the headers using quote
|
||||||
|
- As '(... and not (list...
|
||||||
|
- Do pass the options using quote
|
||||||
|
- As '(... and not (list...
|
||||||
|
|
||||||
|
#### make-c-null
|
||||||
|
<a name="make-c-null"></a>
|
||||||
|
|
||||||
|
**make-c-null** -> pointer
|
||||||
|
|
||||||
|
Returns a new NULL pointer.
|
||||||
|
|
||||||
|
#### c-null?
|
||||||
|
<a name="is-c-null"></a>
|
||||||
|
|
||||||
|
**c-null?** pointer -> boolean
|
||||||
|
|
||||||
|
Returns #t if given pointer is null pointer, #f otherwise.
|
||||||
|
|
||||||
|
#### make-c-bytevector
|
||||||
|
<a name="make-c-bytevector "></a>
|
||||||
|
|
||||||
|
(make-c-bytevector *k*)
|
||||||
|
(make-c-bytevector *k* *fill*)
|
||||||
|
|
||||||
|
Returns a newly allocated C bytevector(pointer) of length k. If byte is given,
|
||||||
|
then all elements of the C bytevector are initialized to byte, otherwise the
|
||||||
|
contents of each element are unspecified.
|
||||||
|
|
||||||
|
#### pffi-pointer-address
|
||||||
|
<a name="pffi-pointer-address"></a>
|
||||||
|
|
||||||
|
**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?
|
||||||
|
<a name="pffi-pointer"></a>
|
||||||
|
|
||||||
|
**c-bytevector?** object -> boolean
|
||||||
|
|
||||||
|
Returns #t if given object is pointer, #f otherwise.
|
||||||
|
|
||||||
|
#### c-free
|
||||||
|
<a name="c-free"></a>
|
||||||
|
|
||||||
|
**c-free** pointer
|
||||||
|
|
||||||
|
Frees given pointer.
|
||||||
|
|
||||||
|
#### pffi-pointer-set!
|
||||||
|
<a name="pffi-pointer-set!"></a>
|
||||||
|
|
||||||
|
**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
|
||||||
|
<a name="pffi-pointer-get"></a>
|
||||||
|
|
||||||
|
**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
|
||||||
|
|
||||||
|
#### utf8->c-bytevector
|
||||||
|
<a name="utf8-into-c-bytevector"></a>
|
||||||
|
|
||||||
|
**utf8->c-bytevector** string -> pointer
|
||||||
|
|
||||||
|
Makes pointer out of a given string.
|
||||||
|
|
||||||
|
#### c-bytevector->string
|
||||||
|
<a name="c-bytevector-into-string"></a>
|
||||||
|
|
||||||
|
**c-bytevector->sring** pointer -> string
|
||||||
|
|
||||||
|
Makes string out of a given pointer.
|
||||||
|
|
||||||
|
#### pffi-struct-make
|
||||||
|
<a name="pffi-struct-make"></a>
|
||||||
|
|
||||||
|
**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
|
||||||
|
<a name="pffi-struct-pointer"></a>
|
||||||
|
|
||||||
|
**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
|
||||||
|
<a name="pffi-struct-offset-get"></a>
|
||||||
|
|
||||||
|
**pffi-struct-offset-get** member-name -> number
|
||||||
|
|
||||||
|
Returns the offset of a struct member with given name.
|
||||||
|
|
||||||
|
#### pffi-struct-get
|
||||||
|
<a name="pffi-struct-get"></a>
|
||||||
|
|
||||||
|
**pffi-struct-get** pffi-struct member-name -> object
|
||||||
|
|
||||||
|
Returns the value of the givens struct member.
|
||||||
|
|
||||||
|
#### pffi-struct-set!
|
||||||
|
<a name="pffi-struct-set!"></a>
|
||||||
|
|
||||||
|
**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
|
||||||
|
<a name="pffi-array-allocate"></a>
|
||||||
|
|
||||||
|
**pffi-array-allocate** type size
|
||||||
|
|
||||||
|
Allocates pointer array of given type and size.
|
||||||
|
|
||||||
|
#### pffi-array-pointer
|
||||||
|
<a name="pffi-array-pointer"></a>
|
||||||
|
|
||||||
|
**pffi-array-pointer** array
|
||||||
|
|
||||||
|
Returns the pointer of the array.
|
||||||
|
|
||||||
|
#### pffi-array?
|
||||||
|
<a name="pffi-array"></a>
|
||||||
|
|
||||||
|
**pffi-array?** object
|
||||||
|
|
||||||
|
Returns #t of given object is array, #f otherwise.
|
||||||
|
|
||||||
|
#### pffi-pointer->array
|
||||||
|
<a name="pffi-pointer->array"></a>
|
||||||
|
|
||||||
|
**pffi-pointer->array** pointer type size
|
||||||
|
|
||||||
|
Converts given pointer to an array of giben type and size.
|
||||||
|
|
||||||
|
#### pffi-array-get
|
||||||
|
<a name="pffi-array-get"></a>
|
||||||
|
|
||||||
|
**pffi-array-get** array index
|
||||||
|
|
||||||
|
Returns the value of given index from given array.
|
||||||
|
|
||||||
|
#### pffi-array-set!
|
||||||
|
<a name="pffi-array-set!"></a>
|
||||||
|
|
||||||
|
**pffi-array-set!** array index value
|
||||||
|
|
||||||
|
Sets the given value of given index in given array.
|
||||||
|
|
||||||
|
#### pffi-list->array
|
||||||
|
<a name="pffi-list->array"></a>
|
||||||
|
|
||||||
|
**pffi-list->array** type list
|
||||||
|
|
||||||
|
Converts given list into C array of given type.
|
||||||
|
|
||||||
|
#### pffi-array->list
|
||||||
|
<a name="pffi-array->list"></a>
|
||||||
|
|
||||||
|
**pffi-array->list** type list length
|
||||||
|
|
||||||
|
Converts given C array into list of given type and length.
|
||||||
|
|
||||||
|
#### define-c-procedure
|
||||||
|
<a name="define-c-procedure"></a>
|
||||||
|
|
||||||
|
**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
|
||||||
|
<a name="pffi-define-callback"></a>
|
||||||
|
|
||||||
|
**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)
|
||||||
|
|
||||||
|
</main>
|
||||||
653
README.md
653
README.md
|
|
@ -1,654 +1,13 @@
|
||||||
---
|
---
|
||||||
title: Portable Foreign Function Interface for R7RS Documentation
|
title: Portable Foreign Function Interface for R7RS Documentation
|
||||||
version: 0.6.0
|
version: 0.10.0
|
||||||
---
|
---
|
||||||
|
|
||||||
# Portable Foreign Function Interface for R7RS
|
# (foreign c)
|
||||||
|
|
||||||
Portable foreign function interface for R7RS. It is portable in the sense that
|
(foreign c) is a C foreign function interface (FFI) library for R7RS. It is
|
||||||
it supports multiple implementations, as opposed to being portable by
|
portable in the sense that it supports multiple implementations, as opposed to
|
||||||
conforming to some specification.
|
being portable by conforming to some specification.
|
||||||
|
|
||||||
[Project](https://todo.sr.ht/~retropikzel/r7rs-pffi)
|
The new readme is a work in progress.
|
||||||
|
|
||||||
[Issue trackers](https://sr.ht/~retropikzel/r7rs-pffi/trackers)
|
|
||||||
|
|
||||||
[Maling lists](https://sr.ht/~retropikzel/r7rs-pffi/lists)
|
|
||||||
|
|
||||||
[Jenkins](https://jenkins.scheme.org/job/r7rs_pffi/job/r7rs-pffi/)
|
|
||||||
|
|
||||||
## Table of contents
|
|
||||||
|
|
||||||
<nav>
|
|
||||||
|
|
||||||
- [Goals](#goals)
|
|
||||||
- [Non Goals](#non-goals)
|
|
||||||
- [Status](#status)
|
|
||||||
- [Current caveats](#current-caveats)
|
|
||||||
- [Roadmap](#roadmap)
|
|
||||||
- [Feature implementation table](#feature-implementation-table)
|
|
||||||
- [Primitives](#feature-implementation-table-primitives)
|
|
||||||
- [Built upon](#feature-implementation-table-built-upon)
|
|
||||||
- [Documentation](#documentation)
|
|
||||||
- [Dependencies](#dependencies)
|
|
||||||
- [Chibi](#dependencies-chibi)
|
|
||||||
- [Chicken](#dependencies-chicken)
|
|
||||||
- [Gauche](#dependencies-gauche)
|
|
||||||
- [Racket](#dependencies-racket)
|
|
||||||
- [Kawa](#dependencies-kawa)
|
|
||||||
- [Installation](#installation)
|
|
||||||
- [Project local](#installation-project-local)
|
|
||||||
- [Linux](#installation-project-local-linux)
|
|
||||||
- [Windows](#installation-project-local-windows)
|
|
||||||
- [System global](#installation-system-global)
|
|
||||||
- [Reference](#reference)
|
|
||||||
- [Types](#types)
|
|
||||||
- [Environment variables](#environment-variables)
|
|
||||||
- [PFFI\_LOAD\_PATH](#environment-variables-pffi-load-path)
|
|
||||||
- [Procedures and macros](#procedures-and-macros)
|
|
||||||
- [pffi-init](#pffi-init)
|
|
||||||
- [c-size-of](#c-size-of)
|
|
||||||
- [pffi-align-of](#pffi-align-of)
|
|
||||||
- [define-c-library](#define-c-library)
|
|
||||||
- [make-c-null](#make-c-null)
|
|
||||||
- [c-null?](#is-c-null)
|
|
||||||
- [make-c-bytevector ](#make-c-bytevector )
|
|
||||||
- [pffi-pointer-address](#pffi-pointer-address)
|
|
||||||
- [c-bytevector?](#is-c-bytevector)
|
|
||||||
- [c-free](#c-free)
|
|
||||||
- [pffi-pointer-set!](#pffi-pointer-set!)
|
|
||||||
- [pffi-pointer-get](#pffi-pointer-get)
|
|
||||||
- [utf8->c-bytevector](#utf8-into-c-bytevector)
|
|
||||||
- [c-bytevector->sring](#c-bytevector-into-string)
|
|
||||||
- [pffi-struct-make](#pffi-struct-make)
|
|
||||||
- [pffi-struct-pointer](#pffi-struct-pointer)
|
|
||||||
- [pffi-struct-offset-get](#pffi-struct-offset-get)
|
|
||||||
- [pffi-struct-get](#pffi-struct-get)
|
|
||||||
- [pffi-struct-set!](#pffi-struct-set!)
|
|
||||||
- [pffi-array-allocate](#pffi-array-allocate)
|
|
||||||
- [pffi-array-pointer](#pffi-array-pointer)
|
|
||||||
- [pffi-array?](#pffi-array)
|
|
||||||
- [pffi-pointer->array](#pffi-pointer->array)
|
|
||||||
- [pffi-array-get](#pffi-array-get)
|
|
||||||
- [pffi-array-set!](#pffi-array-set!)
|
|
||||||
- [pffi-list->array](#pffi-list->array)
|
|
||||||
- [pffi-array->list](#pffi-array->list)
|
|
||||||
- [define-c-procedure](#define-c-procedure)
|
|
||||||
- [pffi-define-callback](#pffi-define-callback)
|
|
||||||
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<main>
|
|
||||||
|
|
||||||
## Goals
|
|
||||||
<a name="goals"></a>
|
|
||||||
|
|
||||||
- Support only R7RS implementations
|
|
||||||
- Same interface on all implementations
|
|
||||||
- Some things that are procedures on one implementation are macros on other,
|
|
||||||
but they must behave the same
|
|
||||||
- Stability and being boring after 1.0.0 is reached
|
|
||||||
|
|
||||||
## Non goals
|
|
||||||
<a name="non-goals"></a>
|
|
||||||
|
|
||||||
- Compiling of used library C code at any point
|
|
||||||
- That is no stubs, no C code generated by the library and so on
|
|
||||||
- The pffi library itself may require compilation on installation
|
|
||||||
|
|
||||||
## Status
|
|
||||||
<a name="status"></a>
|
|
||||||
|
|
||||||
In alpha.
|
|
||||||
|
|
||||||
### Current caveats
|
|
||||||
<a name="current-caveats"></a>
|
|
||||||
|
|
||||||
- No way to pass structs by value
|
|
||||||
- Most implementations are missing callback support
|
|
||||||
- Always pass arguments to pffi functions/macros as '(1 2 3) and not (list 1 2 3)
|
|
||||||
- Always pass pffi-define-callback procedure as lambda in place
|
|
||||||
- No support for variadic function arguments
|
|
||||||
- Can be partially worked around by defining multiple versions of same
|
|
||||||
function with different number of arguments
|
|
||||||
|
|
||||||
## Roadmap
|
|
||||||
|
|
||||||
For roadmap to 1.0.0 see [issues](https://todo.sr.ht/~retropikzel/r7rs-pffi?search=status%3Aopen%20label%3A%221.0.0%22)
|
|
||||||
|
|
||||||
## Feature mplementation table
|
|
||||||
<a name="feature-implementation-table"></a>
|
|
||||||
|
|
||||||
## Primitives
|
|
||||||
<a name="feature-implementation-table-primitives"></a>
|
|
||||||
|
|
||||||
| | c-size-of | define-c-library | c-bytevector? | pffi-pointer-set! | pffi-pointer-get | define-c-procedure | pffi-define-callback |
|
|
||||||
|--------------|:------------:|:-------------------:|:-------------:|:-----------------:|:----------------:|:-------------------:|:--------------------:|
|
|
||||||
| Chibi | X | X | X | X | X | X | |
|
|
||||||
| Chicken | X | X | X | X | X | X | X |
|
|
||||||
| Cyclone | X | X | X | X | X | X | |
|
|
||||||
| Gambit | X | | | | | | |
|
|
||||||
| Gauche | X | X | X | X | X | X | |
|
|
||||||
| Gerbil | | | | | | | |
|
|
||||||
| Guile | X | X | X | X | X | X | X |
|
|
||||||
| Kawa | X | X | X | X | X | X | X |
|
|
||||||
| Larceny | | | | | | | |
|
|
||||||
| Mosh | X | X | X | X | X | X | X |
|
|
||||||
| Racket | X | X | X | X | X | X | X |
|
|
||||||
| Saggittarius | X | X | X | X | X | X | X |
|
|
||||||
| Skint | | | | | | | |
|
|
||||||
| Stklos | X | X | X | | | | |
|
|
||||||
| tr7 | | | | | | | |
|
|
||||||
| Ypsilon | X | X | X | X | X | X | X |
|
|
||||||
|
|
||||||
## Built upon
|
|
||||||
<a name="feature-implementation-table-built-upon"></a>
|
|
||||||
|
|
||||||
These features are built upon the primitives and if primitives are implemented
|
|
||||||
and work, they should work too.
|
|
||||||
|
|
||||||
- make-c-bytevector
|
|
||||||
- make-c-null
|
|
||||||
- c-null?
|
|
||||||
- pffi-pointer-address
|
|
||||||
- c-free
|
|
||||||
- pffi-pointer-\>string
|
|
||||||
- pffi-string-\>pointer
|
|
||||||
- pffi-struct-make
|
|
||||||
- pffi-struct-pointer
|
|
||||||
- pffi-struct-offset-get
|
|
||||||
- pffi-struct-get
|
|
||||||
- pffi-struct-set!
|
|
||||||
- pffi-array-allocate
|
|
||||||
- pffi-array?
|
|
||||||
- pffi-pointer-\>array
|
|
||||||
- pffi-array-get
|
|
||||||
- pffi-array-set!
|
|
||||||
- pffi-list-\>array
|
|
||||||
- pffi-array-\>list
|
|
||||||
|
|
||||||
### Not started
|
|
||||||
<a name="not-started"></a>
|
|
||||||
|
|
||||||
- [LIPS](https://lips.js.org/)
|
|
||||||
- Will work on nodejs by using some C FFI library from npm
|
|
||||||
- Javascript side needs design
|
|
||||||
- [Biwascheme](https://www.biwascheme.org/)
|
|
||||||
- Will work on nodejs by using some C FFI library from npm
|
|
||||||
- Javascript side needs design
|
|
||||||
- [MIT-Scheme](https://www.gnu.org/software/mit-scheme/)
|
|
||||||
- Need to study the implementation more
|
|
||||||
- [Airship](https://gitlab.com/mbabich/airship-scheme)
|
|
||||||
- Need to study the implementation more
|
|
||||||
- [Other gambit targets](https://gambitscheme.org/)
|
|
||||||
- Gambit compiles to different targets other than C too, for example Javascript. It would be cool
|
|
||||||
and interesting to see if this FFI could also support some of those
|
|
||||||
- When LIPS and Biwascheme Javascript side is done then Gambit should be done too
|
|
||||||
- [s48-r7rs](https://codeberg.org/prescheme/s48-r7rs)
|
|
||||||
- Need to study the implementation more
|
|
||||||
- [prescheme](https://codeberg.org/prescheme/prescheme)
|
|
||||||
- Need to study the implementation more
|
|
||||||
|
|
||||||
### Other
|
|
||||||
<a name="other"></a>
|
|
||||||
|
|
||||||
- [s7](https://scheme.fail://ccrma.stanford.edu/software/snd/snd/s7.html)
|
|
||||||
- Propably does not need FFI as it is embeddable only
|
|
||||||
- [Loko](https://scheme.fail/)
|
|
||||||
- Desires no C interop, I can respect that
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
<a name="documentation"></a>
|
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
<a name="dependencies"></a>
|
|
||||||
|
|
||||||
Some implementations have extra dependencies/requirements beyond just the
|
|
||||||
library.
|
|
||||||
|
|
||||||
#### Chibi
|
|
||||||
<a name="dependencies-chibi"></a>
|
|
||||||
|
|
||||||
Building depends on libffi.
|
|
||||||
|
|
||||||
Debian/Ubuntu/Mint install with:
|
|
||||||
|
|
||||||
apt install libffi-dev
|
|
||||||
|
|
||||||
#### Chicken
|
|
||||||
<a name="dependencies-chicken"></a>
|
|
||||||
|
|
||||||
Chicken needs r7rs egg installed. Install it with:
|
|
||||||
|
|
||||||
chicken-install r7rs
|
|
||||||
|
|
||||||
#### Gauche
|
|
||||||
<a name="dependencies-gauche"></a>
|
|
||||||
|
|
||||||
Building depends on libffi.
|
|
||||||
|
|
||||||
Debian/Ubuntu/Mint install with:
|
|
||||||
|
|
||||||
apt install libffi-dev
|
|
||||||
|
|
||||||
#### Racket
|
|
||||||
<a name="dependencies-racket"></a>
|
|
||||||
|
|
||||||
Needs [racket-r7rs](https://github.com/lexi-lambda/racket-r7rs), install with:
|
|
||||||
|
|
||||||
raco pkg install --auto r7rs
|
|
||||||
|
|
||||||
#### Kawa
|
|
||||||
<a name="dependencies-kawa"></a>
|
|
||||||
|
|
||||||
Kawa Needs at least Java version 22 these flags before any other arguments:
|
|
||||||
|
|
||||||
- \-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
|
|
||||||
|
|
||||||
If you are running kawa.jar with plain java then give same arguments to java
|
|
||||||
without the -J prefix.
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
<a name="installation"></a>
|
|
||||||
|
|
||||||
Since the project is under active development is best to clone it from git,
|
|
||||||
|
|
||||||
### Project local
|
|
||||||
<a name="installation-project-local"></a>
|
|
||||||
|
|
||||||
#### Linux
|
|
||||||
<a name="installation-project-local-linux"></a>
|
|
||||||
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
|
|
||||||
<a name="installation-project-local-windows"></a>
|
|
||||||
|
|
||||||
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
|
|
||||||
<a name="installation-system-global"></a>
|
|
||||||
|
|
||||||
Still work in progress.
|
|
||||||
|
|
||||||
## Reference
|
|
||||||
<a name="reference"></a>
|
|
||||||
|
|
||||||
### Types
|
|
||||||
<a name="types"></a>
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
### Types
|
|
||||||
<a name="types"></a>
|
|
||||||
|
|
||||||
### Environment variables
|
|
||||||
<a name="environment-variables"></a>
|
|
||||||
|
|
||||||
Setting environment variables like this on Windows works for this library:
|
|
||||||
|
|
||||||
set "PFFI_LOAD_PATH=C:\Program Files (x86)/foo/bar"
|
|
||||||
|
|
||||||
#### PFFI\_LOAD\_PATH
|
|
||||||
<a name="environment-variables-pffi-load-path"></a>
|
|
||||||
|
|
||||||
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
|
|
||||||
<a name="procedures-and-macros"></a>
|
|
||||||
|
|
||||||
Some of these are procedures and some macros, it might also change implementation to implementation.
|
|
||||||
|
|
||||||
#### pffi-init
|
|
||||||
<a name="pffi-init"></a>
|
|
||||||
|
|
||||||
**pffi-init**
|
|
||||||
|
|
||||||
Always call this first, on most implementation it does nothing but some implementations might need
|
|
||||||
initialisation run.
|
|
||||||
|
|
||||||
#### c-size-of
|
|
||||||
<a name="c-size-of"></a>
|
|
||||||
|
|
||||||
**c-size-of** object -> number
|
|
||||||
|
|
||||||
Returns the size of the pffi-struct, pffi-enum or pffi-type.
|
|
||||||
|
|
||||||
#### pffi-align-of
|
|
||||||
<a name="pffi-align-of"></a>
|
|
||||||
|
|
||||||
**pffi-align-of** type -> number
|
|
||||||
|
|
||||||
Returns the align of the type.
|
|
||||||
|
|
||||||
#### define-c-library
|
|
||||||
<a name="define-c-library"></a>
|
|
||||||
|
|
||||||
**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:
|
|
||||||
|
|
||||||
- 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 for
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
- Do not cond-expand inside the arguments, that might lead to problems on some
|
|
||||||
implementations.
|
|
||||||
- Do not store options in variables, that might lead to problems on some
|
|
||||||
implementations.
|
|
||||||
- Do pass the headers using quote
|
|
||||||
- As '(... and not (list...
|
|
||||||
- Do pass the options using quote
|
|
||||||
- As '(... and not (list...
|
|
||||||
|
|
||||||
#### make-c-null
|
|
||||||
<a name="make-c-null"></a>
|
|
||||||
|
|
||||||
**make-c-null** -> pointer
|
|
||||||
|
|
||||||
Returns a new NULL pointer.
|
|
||||||
|
|
||||||
#### c-null?
|
|
||||||
<a name="is-c-null"></a>
|
|
||||||
|
|
||||||
**c-null?** pointer -> boolean
|
|
||||||
|
|
||||||
Returns #t if given pointer is null pointer, #f otherwise.
|
|
||||||
|
|
||||||
#### make-c-bytevector
|
|
||||||
<a name="make-c-bytevector "></a>
|
|
||||||
|
|
||||||
(make-c-bytevector *k*)
|
|
||||||
(make-c-bytevector *k* *fill*)
|
|
||||||
|
|
||||||
Returns a newly allocated C bytevector(pointer) of length k. If byte is given,
|
|
||||||
then all elements of the C bytevector are initialized to byte, otherwise the
|
|
||||||
contents of each element are unspecified.
|
|
||||||
|
|
||||||
#### pffi-pointer-address
|
|
||||||
<a name="pffi-pointer-address"></a>
|
|
||||||
|
|
||||||
**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?
|
|
||||||
<a name="pffi-pointer"></a>
|
|
||||||
|
|
||||||
**c-bytevector?** object -> boolean
|
|
||||||
|
|
||||||
Returns #t if given object is pointer, #f otherwise.
|
|
||||||
|
|
||||||
#### c-free
|
|
||||||
<a name="c-free"></a>
|
|
||||||
|
|
||||||
**c-free** pointer
|
|
||||||
|
|
||||||
Frees given pointer.
|
|
||||||
|
|
||||||
#### pffi-pointer-set!
|
|
||||||
<a name="pffi-pointer-set!"></a>
|
|
||||||
|
|
||||||
**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
|
|
||||||
<a name="pffi-pointer-get"></a>
|
|
||||||
|
|
||||||
**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
|
|
||||||
|
|
||||||
#### utf8->c-bytevector
|
|
||||||
<a name="utf8-into-c-bytevector"></a>
|
|
||||||
|
|
||||||
**utf8->c-bytevector** string -> pointer
|
|
||||||
|
|
||||||
Makes pointer out of a given string.
|
|
||||||
|
|
||||||
#### c-bytevector->string
|
|
||||||
<a name="c-bytevector-into-string"></a>
|
|
||||||
|
|
||||||
**c-bytevector->sring** pointer -> string
|
|
||||||
|
|
||||||
Makes string out of a given pointer.
|
|
||||||
|
|
||||||
#### pffi-struct-make
|
|
||||||
<a name="pffi-struct-make"></a>
|
|
||||||
|
|
||||||
**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
|
|
||||||
<a name="pffi-struct-pointer"></a>
|
|
||||||
|
|
||||||
**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
|
|
||||||
<a name="pffi-struct-offset-get"></a>
|
|
||||||
|
|
||||||
**pffi-struct-offset-get** member-name -> number
|
|
||||||
|
|
||||||
Returns the offset of a struct member with given name.
|
|
||||||
|
|
||||||
#### pffi-struct-get
|
|
||||||
<a name="pffi-struct-get"></a>
|
|
||||||
|
|
||||||
**pffi-struct-get** pffi-struct member-name -> object
|
|
||||||
|
|
||||||
Returns the value of the givens struct member.
|
|
||||||
|
|
||||||
#### pffi-struct-set!
|
|
||||||
<a name="pffi-struct-set!"></a>
|
|
||||||
|
|
||||||
**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
|
|
||||||
<a name="pffi-array-allocate"></a>
|
|
||||||
|
|
||||||
**pffi-array-allocate** type size
|
|
||||||
|
|
||||||
Allocates pointer array of given type and size.
|
|
||||||
|
|
||||||
#### pffi-array-pointer
|
|
||||||
<a name="pffi-array-pointer"></a>
|
|
||||||
|
|
||||||
**pffi-array-pointer** array
|
|
||||||
|
|
||||||
Returns the pointer of the array.
|
|
||||||
|
|
||||||
#### pffi-array?
|
|
||||||
<a name="pffi-array"></a>
|
|
||||||
|
|
||||||
**pffi-array?** object
|
|
||||||
|
|
||||||
Returns #t of given object is array, #f otherwise.
|
|
||||||
|
|
||||||
#### pffi-pointer->array
|
|
||||||
<a name="pffi-pointer->array"></a>
|
|
||||||
|
|
||||||
**pffi-pointer->array** pointer type size
|
|
||||||
|
|
||||||
Converts given pointer to an array of giben type and size.
|
|
||||||
|
|
||||||
#### pffi-array-get
|
|
||||||
<a name="pffi-array-get"></a>
|
|
||||||
|
|
||||||
**pffi-array-get** array index
|
|
||||||
|
|
||||||
Returns the value of given index from given array.
|
|
||||||
|
|
||||||
#### pffi-array-set!
|
|
||||||
<a name="pffi-array-set!"></a>
|
|
||||||
|
|
||||||
**pffi-array-set!** array index value
|
|
||||||
|
|
||||||
Sets the given value of given index in given array.
|
|
||||||
|
|
||||||
#### pffi-list->array
|
|
||||||
<a name="pffi-list->array"></a>
|
|
||||||
|
|
||||||
**pffi-list->array** type list
|
|
||||||
|
|
||||||
Converts given list into C array of given type.
|
|
||||||
|
|
||||||
#### pffi-array->list
|
|
||||||
<a name="pffi-array->list"></a>
|
|
||||||
|
|
||||||
**pffi-array->list** type list length
|
|
||||||
|
|
||||||
Converts given C array into list of given type and length.
|
|
||||||
|
|
||||||
#### define-c-procedure
|
|
||||||
<a name="define-c-procedure"></a>
|
|
||||||
|
|
||||||
**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
|
|
||||||
<a name="pffi-define-callback"></a>
|
|
||||||
|
|
||||||
**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)
|
|
||||||
|
|
||||||
</main>
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
(define-library
|
(define-library
|
||||||
(retropikzel pffi) ; (foreign r7rs)? (foreign c)?
|
(foreign c)
|
||||||
(cond-expand
|
(cond-expand
|
||||||
(chibi
|
(chibi
|
||||||
(import (scheme base)
|
(import (scheme base)
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
(chibi ast)
|
(chibi ast)
|
||||||
(scheme inexact)
|
(scheme inexact)
|
||||||
(chibi))
|
(chibi))
|
||||||
(include-shared "pffi/chibi-pffi"))
|
(include-shared "c/lib/chibi"))
|
||||||
(chicken
|
(chicken
|
||||||
(import (scheme base)
|
(import (scheme base)
|
||||||
(scheme write)
|
(scheme write)
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
(scheme inexact)
|
(scheme inexact)
|
||||||
(scheme process-context)
|
(scheme process-context)
|
||||||
(gauche base)
|
(gauche base)
|
||||||
(retropikzel pffi gauche)))
|
(foreign c primitives gauche)))
|
||||||
(gerbil
|
(gerbil
|
||||||
(import (scheme base)
|
(import (scheme base)
|
||||||
(scheme write)
|
(scheme write)
|
||||||
|
|
@ -293,38 +293,39 @@
|
||||||
;define-c-variable (?)
|
;define-c-variable (?)
|
||||||
)
|
)
|
||||||
(cond-expand
|
(cond-expand
|
||||||
(chibi (include "pffi/chibi.scm"))
|
(chibi (include "c/primitives/chibi.scm"))
|
||||||
(chicken-5 (export foreign-declare
|
(chicken-5 (export foreign-declare
|
||||||
foreign-safe-lambda
|
foreign-safe-lambda
|
||||||
void)
|
void)
|
||||||
(include "pffi/chicken.scm"))
|
(include "c/primitives/chicken.scm"))
|
||||||
(chicken-6 (include-relative "pffi/chicken.scm"))
|
(chicken-6 (include-relative "c/primitives/chicken.scm"))
|
||||||
(cyclone (export calculate-struct-size-and-offsets
|
(cyclone (export calculate-struct-size-and-offsets
|
||||||
struct-make)
|
struct-make)
|
||||||
(include "pffi/cyclone.scm"))
|
(include "c/primitives/cyclone.scm"))
|
||||||
(gambit (include "pffi/gambit.scm"))
|
(gambit (include "c/primitives/gambit.scm"))
|
||||||
(gauche (include "pffi/gauche.scm"))
|
(gauche (include "c/primitives/gauche.scm"))
|
||||||
(gerbil (include "pffi/gerbil.scm"))
|
(gerbil (include "c/primitives/gerbil.scm"))
|
||||||
(guile (include "pffi/guile.scm"))
|
(guile (include "c/primitives/guile.scm"))
|
||||||
(kawa (include "pffi/kawa.scm"))
|
(kawa (include "c/primitives/kawa.scm"))
|
||||||
(larceny (include "pffi/larceny.scm"))
|
(larceny (include "c/primitives/larceny.scm"))
|
||||||
(mosh (include "pffi/mosh.scm"))
|
(mosh (include "c/primitives/mosh.scm"))
|
||||||
(racket (include "pffi/racket.scm"))
|
(racket (include "c/primitives/racket.scm"))
|
||||||
(sagittarius (include "pffi/sagittarius.scm"))
|
(sagittarius (include "c/primitives/sagittarius.scm"))
|
||||||
(skint (include "pffi/skint.scm"))
|
(skint (include "c/primitives/skint.scm"))
|
||||||
(stklos (include "pffi/stklos.scm"))
|
(stklos (include "c/primitives/stklos.scm"))
|
||||||
(tr7 (include "pffi/tr7.scm"))
|
(tr7 (include "c/primitives/tr7.scm"))
|
||||||
(ypsilon (export c-function c-callback)
|
(ypsilon (export c-function c-callback)
|
||||||
(include "pffi/ypsilon.scm")))
|
(include "c/primitives/ypsilon.scm")))
|
||||||
(cond-expand
|
(cond-expand
|
||||||
(chicken-6 (include-relative "pffi/shared/main.scm")
|
(chicken-6 (include-relative "c/main.scm")
|
||||||
(include-relative "pffi/shared/pointer.scm")
|
(include-relative "c/c-bytevectors.scm")
|
||||||
;(include-relative "pffi/shared/array.scm")
|
(include-relative "c/pointer.scm")
|
||||||
;(include-relative "pffi/shared/struct.scm")
|
;(include-relative "c/array.scm")
|
||||||
|
;(include-relative "c/struct.scm")
|
||||||
)
|
)
|
||||||
(else (include "pffi/shared/main.scm")
|
(else (include "c/main.scm")
|
||||||
;(include "pffi/shared/struct.scm")
|
;(include "c/struct.scm")
|
||||||
(include "pffi/shared/c-bytevectors.scm")
|
(include "c/c-bytevectors.scm")
|
||||||
(include "pffi/shared/pointer.scm")
|
(include "c/pointer.scm")
|
||||||
;(include "pffi/shared/array.scm")
|
;(include "c/array.scm")
|
||||||
)))
|
)))
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
CC=gcc
|
CC=gcc
|
||||||
|
|
||||||
chibi: chibi-src/pffi.stub
|
chibi: primitives/chibi/foreign-c.stub
|
||||||
chibi-ffi chibi-src/pffi.stub
|
chibi-ffi primitives/chibi/foreign-c.stub
|
||||||
${CC} -g3 -o chibi-pffi.so chibi-src/pffi.c -fPIC -lffi -shared
|
mkdir -p lib
|
||||||
|
${CC} -g3 -o lib/chibi.so primitives/chibi/foreign-c.c -fPIC -lffi -shared
|
||||||
|
|
||||||
chicken:
|
chicken:
|
||||||
@echo "Nothing to build for Chicken"
|
@echo "Nothing to build for Chicken"
|
||||||
|
|
@ -13,13 +14,17 @@ cyclone:
|
||||||
gambit:
|
gambit:
|
||||||
@echo "Nothing to build for Gambit"
|
@echo "Nothing to build for Gambit"
|
||||||
|
|
||||||
gauche: gauche-src/gauche-pffi.c gauche-src/gauchelib.scm
|
gauche: primitives/gauche/foreign-c-primitives-gauche.c primitives/gauche/gauchelib.scm
|
||||||
gauche-package compile \
|
gauche-package compile \
|
||||||
--srcdir=gauche-src \
|
--srcdir=primitives/gauche \
|
||||||
--cc=${CC} \
|
--cc=${CC} \
|
||||||
--cflags="-I./include" \
|
--cflags="-I./primitives/include" \
|
||||||
--libs=-lffi \
|
--libs=-lffi \
|
||||||
gauche-pffi gauche-pffi.c gauchelib.scm
|
foreign-c-primitives-gauche foreign-c-primitives-gauche.c gauchelib.scm
|
||||||
|
mkdir -p lib
|
||||||
|
mv foreign-c-primitives-gauche.so lib/gauche.so
|
||||||
|
mv foreign-c-primitives-gauche.o lib/gauche.o
|
||||||
|
|
||||||
|
|
||||||
gerbil:
|
gerbil:
|
||||||
@echo "Nothing to build for Gerbil"
|
@echo "Nothing to build for Gerbil"
|
||||||
|
|
@ -53,3 +58,7 @@ tr7:
|
||||||
|
|
||||||
ypsilon:
|
ypsilon:
|
||||||
@echo "Nothing to build for Ypsilon"
|
@echo "Nothing to build for Ypsilon"
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -rf primitives/chibi/foreign-c.c
|
||||||
|
@rm -rf lib
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
(define-module retropikzel.pffi.gauche
|
(define-module foreign.c.primitives.gauche
|
||||||
(export size-of-type
|
(export size-of-type
|
||||||
pffi-shared-object-load
|
pffi-shared-object-load
|
||||||
c-bytevector-u8-set!
|
c-bytevector-u8-set!
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
define-c-procedure
|
define-c-procedure
|
||||||
define-c-callback))
|
define-c-callback))
|
||||||
|
|
||||||
(select-module retropikzel.pffi.gauche)
|
(select-module foreign.c.primitives.gauche)
|
||||||
(dynamic-load "retropikzel/pffi/gauche-pffi")
|
(dynamic-load "foreign/c/lib/gauche")
|
||||||
|
|
||||||
(define size-of-type
|
(define size-of-type
|
||||||
(lambda (type)
|
(lambda (type)
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
(in-module retropikzel.pffi.gauche)
|
(in-module foreign.c.primitives.gauche)
|
||||||
|
|
||||||
(inline-stub
|
(inline-stub
|
||||||
(.include "gauche-pffi.h")
|
(.include "foreign-c-primitives-gauche.h")
|
||||||
(define-cproc size-of-int8 () size_of_int8)
|
(define-cproc size-of-int8 () size_of_int8)
|
||||||
(define-cproc size-of-uint8 () size_of_uint8)
|
(define-cproc size-of-uint8 () size_of_uint8)
|
||||||
(define-cproc size-of-int16 () size_of_int16)
|
(define-cproc size-of-int16 () size_of_int16)
|
||||||
|
|
@ -71,8 +71,8 @@
|
||||||
(define-cproc pointer-get-double (pointer offset::<int>) pointer_get_double)
|
(define-cproc pointer-get-double (pointer offset::<int>) pointer_get_double)
|
||||||
(define-cproc pointer-get-pointer (pointer offset::<int>) pointer_get_pointer)
|
(define-cproc pointer-get-pointer (pointer offset::<int>) pointer_get_pointer)
|
||||||
|
|
||||||
(define-cproc dlerror () pffi_dlerror)
|
(define-cproc dlerror () internal_dlerror)
|
||||||
(define-cproc dlsym (shared-object c-name) pffi_dlsym)
|
(define-cproc dlsym (shared-object c-name) internal_dlsym)
|
||||||
(define-cproc internal-ffi-call (nargs rtype atypes fn rvalue avalues) internal_ffi_call)
|
(define-cproc internal-ffi-call (nargs rtype atypes fn rvalue avalues) internal_ffi_call)
|
||||||
(define-cproc scheme-procedure-to-pointer (procedure) scheme_procedure_to_pointer)
|
(define-cproc scheme-procedure-to-pointer (procedure) scheme_procedure_to_pointer)
|
||||||
|
|
||||||
14
package.scm
14
package.scm
|
|
@ -1,16 +1,16 @@
|
||||||
(package
|
(package
|
||||||
(name (retropikzel pffi))
|
(name (foreign c))
|
||||||
(authors "Retropikzel")
|
(authors "Retropikzel <retropikzel@iki.fi>")
|
||||||
(maintainers "Retropikzel")
|
(maintainers "Retropikzel <retropikzel@iki.fi>")
|
||||||
(homepage "https://git.sr.ht/~retropikzel/r7rs-pffi")
|
(homepage "https://git.sr.ht/~retropikzel/foreign-c")
|
||||||
(manual "README.md")
|
(manual "README.md")
|
||||||
(description "Portable Foreign Function Interface for R7RS schemes")
|
(description "Portable Foreign Function Interface for R7RS schemes")
|
||||||
(keywords 'ffi)
|
(keywords 'ffi)
|
||||||
(license 'lgpl)
|
(license 'lgpl)
|
||||||
(version "0.6.0")
|
(version "0.10.0")
|
||||||
(test "test.scm")
|
(test "test.scm")
|
||||||
(library
|
(library
|
||||||
(name (retropikzel pffi))
|
(name (foreign c))
|
||||||
(path "retropikzel/pffi.sld")
|
(path "foreign/c.sld")
|
||||||
(depends)
|
(depends)
|
||||||
(platforms linux windows)))
|
(platforms linux windows)))
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
(scheme char)
|
(scheme char)
|
||||||
(scheme file)
|
(scheme file)
|
||||||
(scheme process-context)
|
(scheme process-context)
|
||||||
(retropikzel pffi))
|
(foreign c))
|
||||||
|
|
||||||
;; util
|
;; util
|
||||||
(define header-count 1)
|
(define header-count 1)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
(scheme char)
|
(scheme char)
|
||||||
(scheme file)
|
(scheme file)
|
||||||
(scheme process-context)
|
(scheme process-context)
|
||||||
(retropikzel pffi))
|
(foreign c))
|
||||||
|
|
||||||
(define header-count 1)
|
(define header-count 1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
(scheme char)
|
(scheme char)
|
||||||
(scheme file)
|
(scheme file)
|
||||||
(scheme process-context)
|
(scheme process-context)
|
||||||
(retropikzel pffi))
|
(foreign c))
|
||||||
|
|
||||||
;; util
|
;; util
|
||||||
(define header-count 1)
|
(define header-count 1)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue