Updated documentation

This commit is contained in:
retropikzel 2025-05-03 07:05:12 +03:00
parent 862b6f2eda
commit 0184f043f1
4 changed files with 158 additions and 45 deletions

View File

@ -123,8 +123,6 @@ Types are given as symbols, for example 'int8 or 'pointer.
Returns the size of given C type. Returns the size of given C type.
***
(**define-c-library** _scheme-name_ _headers_ _object-name_ _options_) (**define-c-library** _scheme-name_ _headers_ _object-name_ _options_)
Takes a scheme-name to bind the library to, list of C headers as Takes a scheme-name to bind the library to, list of C headers as
@ -269,16 +267,7 @@ Example:
### c-bytevector ### c-bytevector
(**make-c-bytevector** _k_) #### Creation and deletion
(**make-c-bytevector** _k_ _fill_)
Returns a newly allocated c-bytevector of _k_ 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 uint8_t values
, it specifies the initial value for the bytes of the c-bytevector
(**make-c-null**) (**make-c-null**)
@ -292,7 +281,23 @@ Returns **#t** if _obj_ is a null C pointer, otherwise returns **#f**.
Frees _c-bytevector_ from memory. Frees _c-bytevector_ from memory.
native-endianness (**make-c-bytevector** _k_)
(**make-c-bytevector** _k_ _fill_)
Returns a newly allocated c-bytevector of _k_ 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 uint8_t values
, it specifies the initial value for the bytes of the c-bytevector
#### Accessors
(**native-endianness**)
c-bytevector-s8-set! c-bytevector-s8-set!
c-bytevector-s8-ref c-bytevector-s8-ref
c-bytevector-s16-set! c-bytevector-s16-set!

View File

@ -2,8 +2,8 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>foreign-c a portable foreign function interface for <title>foreign-c a portable foreign function interface for R7RS
R7RS - 0.10.0</title> Schemes - 0.10.0</title>
<style> <style>
table { width: 250%; } table { width: 250%; }
nav { float: left; width: 20%;} nav { float: left; width: 20%;}
@ -14,23 +14,20 @@ R7RS - 0.10.0</title>
<body> <body>
<h1 id="foreign-c">foreign-c</h1> <h1 id="foreign-c">foreign-c</h1>
<p>foreign-c is a C foreign function interface (FFI) library for <p>foreign-c is a C foreign function interface (FFI) library for
R7RS. It is portable in the sense that it supports multiple R7RS Schemes. It is portable in the sense that it supports
implementations, as opposed to being portable by conforming to multiple implementations, as opposed to being portable by
some specification.</p> conforming to some specification.</p>
<p><a <p><a href="https://sr.ht/~retropikzel/foreign-c/trackers">Issue
href="https://todo.sr.ht/~retropikzel/r7rs-pffi">Project</a></p> tracker</a></p>
<p><a href="https://sr.ht/~retropikzel/r7rs-pffi/trackers">Issue <p><a href="https://sr.ht/~retropikzel/foreign-c/lists">Maling
trackers</a></p>
<p><a href="https://sr.ht/~retropikzel/r7rs-pffi/lists">Maling
lists</a></p> lists</a></p>
<p><a
href="https://jenkins.scheme.org/job/r7rs_pffi/job/r7rs-pffi/">Jenkins</a></p>
<ul> <ul>
<li><a href="#installation">Installation</a></li> <li><a href="#installation">Installation</a></li>
<li><a href="#documentation">Documentation</a> <li><a href="#documentation">Documentation</a>
<ul> <ul>
<li><a href="#types">Types</a></li> <li><a href="#types">Types</a></li>
<li><a href="#primitives">Primitives</a></li> <li><a href="#primitives-1">Primitives 1</a></li>
<li><a href="#primitives-2">Primitives 2</a></li>
<li><a href="#c-bytevector">c-bytevector</a></li> <li><a href="#c-bytevector">c-bytevector</a></li>
<li><a href="#environment-variables">Environment <li><a href="#environment-variables">Environment
variables</a></li> variables</a></li>
@ -38,7 +35,7 @@ R7RS - 0.10.0</title>
</ul> </ul>
<h2 id="implementation-support-tables">Implementation support <h2 id="implementation-support-tables">Implementation support
tables</h2> tables</h2>
<h3 id="primitives-1">Primitives 1</h3> <h3 id="primitives-1-table">Primitives 1 table</h3>
<table> <table>
<colgroup> <colgroup>
<col style="width: 13%" /> <col style="width: 13%" />
@ -153,7 +150,7 @@ R7RS - 0.10.0</title>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<h3 id="primitives-2">Primitives 2</h3> <h3 id="primitives-2-table">Primitives 2 table</h3>
<table> <table>
<thead> <thead>
<tr class="header"> <tr class="header">
@ -280,14 +277,13 @@ R7RS - 0.10.0</title>
<h3 id="installation">Installation</h3> <h3 id="installation">Installation</h3>
<p>Either download the latest release from <a <p>Either download the latest release from <a
href="https://git.sr.ht/~retropikzel/foreign-c/refs">https://git.sr.ht/~retropikzel/foreign-c/refs</a> href="https://git.sr.ht/~retropikzel/foreign-c/refs">https://git.sr.ht/~retropikzel/foreign-c/refs</a>
or git clone , preferably with a tag, and copy the “foreign” or git clone , preferably with a tag, and copy the
directory to your library directory.</p> <em>foreign</em> directory to your library directory.</p>
<p>As an example assuming you have a project and your libraries <p>Example assuming libraries in directory <em>snow</em>:</p>
live in directory called snow in it:</p>
<pre><code>git clone https://git.sr.ht/~retropikzel/foreign-c --branch LATEST_VERSION <pre><code>git clone https://git.sr.ht/~retropikzel/foreign-c --branch LATEST_VERSION
mkdir -p snow mkdir -p snow
cp -r foreign-c/foreign snow/ cp -r foreign-c/foreign snow/
make -C snow/foreign/c &lt;SCHEME_IMPLEMENTATION_NAME&gt;</code></pre> make -C snow/foreign/c SCHEME_IMPLEMENTATION_NAME</code></pre>
<p>With most implementations the make command does not compile <p>With most implementations the make command does not compile
anything. When that is the case it will say “Nothing to build on anything. When that is the case it will say “Nothing to build on
SCHEME_IMPLEMENTATION_NAME.”</p> SCHEME_IMPLEMENTATION_NAME.”</p>
@ -314,13 +310,20 @@ make -C snow/foreign/c &lt;SCHEME_IMPLEMENTATION_NAME&gt;</code></pre>
<li>unsigned-long</li> <li>unsigned-long</li>
<li>float</li> <li>float</li>
<li>double</li> <li>double</li>
<li>pointer</li> <li>pointer
<ul>
<li>c-bytevector on Scheme side</li>
</ul></li>
<li>callback <li>callback
<ul> <ul>
<li>Callback function</li> <li>Callback function</li>
</ul></li> </ul></li>
<li>void
<ul>
<li>Can not be argument type, only return type</li>
</ul></li>
</ul> </ul>
<h3 id="primitives">Primitives</h3> <h3 id="primitives-1">Primitives 1</h3>
<p>(<strong>c-type-size</strong> <em>type</em>)</p> <p>(<strong>c-type-size</strong> <em>type</em>)</p>
<p>Returns the size of given C type.</p> <p>Returns the size of given C type.</p>
<p>(<strong>define-c-library</strong> <em>scheme-name</em> <p>(<strong>define-c-library</strong> <em>scheme-name</em>
@ -331,7 +334,7 @@ make -C snow/foreign/c &lt;SCHEME_IMPLEMENTATION_NAME&gt;</code></pre>
they are added automatically.</p> they are added automatically.</p>
<p>The name of the shared object should not contain suffix like <p>The name of the shared object should not contain suffix like
.so or .dll. Nor should it contain any prefix like “lib”.</p> .so or .dll. Nor should it contain any prefix like “lib”.</p>
<p>The options are:</p> <p>Options:</p>
<ul> <ul>
<li>additional-versions <li>additional-versions
<ul> <ul>
@ -363,20 +366,125 @@ make -C snow/foreign/c &lt;SCHEME_IMPLEMENTATION_NAME&gt;</code></pre>
problems on some implementations.</li> problems on some implementations.</li>
<li>Do not store options in variables, that might lead to <li>Do not store options in variables, that might lead to
problems on some implementations.</li> problems on some implementations.</li>
<li>Do pass the headers using quote <li>Pass the headers using quote
<ul> <ul>
<li>As (… and not (list…</li> <li>As (…) and not (list…)</li>
</ul></li> </ul></li>
<li>Do pass the options using quote <li>Pass the options using quote
<ul> <ul>
<li>As (… and not (list… define-c-procedure define-c-callback <li>As (…) and not (list…)</li>
c-bytevector? c-bytevector-u8-set! c-bytevector-u8-ref
c-bytevector-pointer-set! c-bytevector-pointer-ref</li>
</ul></li> </ul></li>
</ul> </ul>
<p>(<strong>define-c-procedure</strong> <em>scheme-name</em>
<em>shared-object</em> <em>c-name</em> <em>return-type</em>
<em>argument-type</em>)</p>
<p>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.</p>
<p>Defines a new foreign function to be used from Scheme
code.</p>
<p>Example:</p>
<pre><code>(cond-expand
(windows (define-c-library libc-stdlib &#39;(&quot;stdlib.h&quot;) &quot;ucrtbase&quot; &#39;()))
(else (define-c-library libc-stdlib &#39;(&quot;stdlib.h&quot;) &quot;c&quot; &#39;(&quot;6&quot;))))
(define-c-procedure c-puts libc-stdlib &#39;puts &#39;int &#39;(pointer))
(c-puts &quot;Message brought to you by foreign-c!&quot;)</code></pre>
<h4 id="notes-1">Notes</h4>
<ul>
<li>Pass the return-types using quote
<ul>
<li>As (…) and not (list…)</li>
</ul></li>
</ul>
<p>(<strong>c-bytevector?</strong> <em>obj</em>)</p>
<p>Returns <strong>#t</strong> if <em>obj</em> is c-bytevector,
otherwise returns <strong>#f</strong>.</p>
<p>(<strong>c-bytevector-u8-set!</strong> <em>c-bytevector</em>
<em>k</em> <em>byte</em>)</p>
<p>If K is not a valid index of c-bytevector the behaviour is
undefined.</p>
<p>Stores the byte in element k of c-bytevector.</p>
<p>(<strong>c-bytevector-u8-ref</strong> <em>c-bytevector</em>
<em>k</em>)</p>
<p>If K is not a valid index of c-bytevector the behaviour is
undefined.</p>
<p>Returns the byte at index k of c-bytevector.</p>
<p>(<strong>c-bytevector-pointer-set!</strong>
<em>c-bytevector</em> <em>k</em> <em>pointer</em>)</p>
<p>If K is not a valid index of c-bytevector the behaviour is
undefined.</p>
<p>Stores the pointer(which is also c-bytevector) in element k
of c-bytevector.</p>
<p>(<strong>c-bytevector-pointer-ref</strong>
<em>c-bytevector</em> <em>k</em> <em>pointer</em>)</p>
<p>If K is not a valid index of c-bytevector the behaviour is
undefined.</p>
<p>Returns the pointer(which is also c-bytevector) at index k of
c-bytevector.</p>
<h3 id="primitives-2">Primitives 2</h3>
<p>(<strong>define-c-callback</strong> <em>scheme-name</em>
<em>return-type</em> <em>argument-types</em>
<em>procedure</em>)</p>
<p>Takes scheme-name to bind the Scheme procedure to,
return-type, argument-types and procedure as in place
lambda.</p>
<p>Defines a new Sceme function to be used as callback to C
code.</p>
<p>Example:</p>
<pre><code>; Load the shared library
(cond-expand
(windows (define-c-library libc-stdlib &#39;(&quot;stdlib.h&quot;) &quot;ucrtbase&quot; &#39;()))
(else (define-c-library &#39;(&quot;stdlib.h&quot;) &quot;c&quot; &#39;(&quot;&quot; &quot;6&quot;))))
; Define C function that takes a callback
(define-c-procedure qsort libc-stdlib &#39;qsort &#39;void &#39;(pointer int int callback))
; Define our callback
(pffi-define-callback compare
&#39;int
&#39;(pointer pointer)
(lambda (pointer-a pointer-b)
(let ((a (pffi-pointer-get pointer-a &#39;int 0))
(b (pffi-pointer-get pointer-b &#39;int 0)))
(cond ((&gt; a b) 1)
((= a b) 0)
((&lt; a b) -1)))))
; Create new array of ints to be sorted
(define array (make-c-bytevector (* (c-size-of &#39;int) 3)))
(pffi-pointer-set! array &#39;int (* (c-size-of &#39;int) 0) 3)
(pffi-pointer-set! array &#39;int (* (c-size-of &#39;int) 1) 2)
(pffi-pointer-set! array &#39;int (* (c-size-of &#39;int) 2) 1)
(display array)
(newline)
;&gt; (3 2 1)
; Sort the array
(qsort array 3 (c-size-of &#39;int) compare)
(display array)
(newline)
;&gt; (1 2 3)</code></pre>
<h3 id="c-bytevector">c-bytevector</h3> <h3 id="c-bytevector">c-bytevector</h3>
<p>make-c-bytevector make-c-null c-null? c-free <p>(<strong>make-c-bytevector</strong> <em>k</em>)
native-endianness c-bytevector-s8-set! c-bytevector-s8-ref (<strong>make-c-bytevector</strong> <em>k</em>
<em>fill</em>)</p>
<p>Returns a newly allocated c-bytevector of <em>k</em>
bytes.</p>
<p>If the <em>fill</em> argument is missing, the initial
contents of the returned c-bytevector are unspecified.</p>
<p>If the <em>fill</em> argument is present, its value must
confine to C uint8_t values , it specifies the initial value for
the bytes of the c-bytevector</p>
<p>(<strong>make-c-null</strong>)</p>
<p>Returns a null C pointer.</p>
<p>(<strong>c-null?</strong> <em>obj</em>)</p>
<p>Returns <strong>#t</strong> if <em>obj</em> is a null C
pointer, otherwise returns <strong>#f</strong>.</p>
<p>(<strong>c-free</strong> <em>c-bytevector</em>)</p>
<p>Frees <em>c-bytevector</em> from memory.</p>
<p>native-endianness c-bytevector-s8-set! c-bytevector-s8-ref
c-bytevector-s16-set! c-bytevector-s16-ref c-bytevector-s16-set! c-bytevector-s16-ref
c-bytevector-s16-native-set! c-bytevector-s16-native-ref c-bytevector-s16-native-set! c-bytevector-s16-native-ref
c-bytevector-u16-set! c-bytevector-u16-ref c-bytevector-u16-set! c-bytevector-u16-ref

Binary file not shown.

View File

@ -219,10 +219,10 @@
c-bytevector-pointer-ref c-bytevector-pointer-ref
;;;; c-bytevector ;;;; c-bytevector
make-c-bytevector
make-c-null make-c-null
c-null? c-null?
c-free c-free
make-c-bytevector
native-endianness native-endianness
c-bytevector-s8-set! c-bytevector-s8-set!
c-bytevector-s8-ref c-bytevector-s8-ref