187 lines
8.8 KiB
HTML
187 lines
8.8 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<!-- Created by GNU Texinfo 7.1, https://www.gnu.org/software/texinfo/ -->
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<!-- This manual documents Guile version 3.0.10.
|
|
|
|
Copyright (C) 1996-1997, 2000-2005, 2009-2023 Free Software Foundation,
|
|
Inc.
|
|
|
|
Copyright (C) 2021 Maxime Devos
|
|
|
|
Copyright (C) 2024 Tomas Volf
|
|
|
|
|
|
Permission is granted to copy, distribute and/or modify this document
|
|
under the terms of the GNU Free Documentation License, Version 1.3 or
|
|
any later version published by the Free Software Foundation; with no
|
|
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
|
|
copy of the license is included in the section entitled "GNU Free
|
|
Documentation License." -->
|
|
<title>Foreign Objects and Scheme (Guile Reference Manual)</title>
|
|
|
|
<meta name="description" content="Foreign Objects and Scheme (Guile Reference Manual)">
|
|
<meta name="keywords" content="Foreign Objects and Scheme (Guile Reference Manual)">
|
|
<meta name="resource-type" content="document">
|
|
<meta name="distribution" content="global">
|
|
<meta name="Generator" content=".texi2any-real">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
|
|
<link href="index.html" rel="start" title="Top">
|
|
<link href="Concept-Index.html" rel="index" title="Concept Index">
|
|
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
|
|
<link href="Defining-New-Foreign-Object-Types.html" rel="up" title="Defining New Foreign Object Types">
|
|
<link href="Foreign-Object-Memory-Management.html" rel="prev" title="Foreign Object Memory Management">
|
|
<style type="text/css">
|
|
<!--
|
|
a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
|
|
div.example {margin-left: 3.2em}
|
|
span:hover a.copiable-link {visibility: visible}
|
|
-->
|
|
</style>
|
|
<link rel="stylesheet" type="text/css" href="https://www.gnu.org/software/gnulib/manual.css">
|
|
|
|
|
|
</head>
|
|
|
|
<body lang="en">
|
|
<div class="subsection-level-extent" id="Foreign-Objects-and-Scheme">
|
|
<div class="nav-panel">
|
|
<p>
|
|
Previous: <a href="Foreign-Object-Memory-Management.html" accesskey="p" rel="prev">Foreign Object Memory Management</a>, Up: <a href="Defining-New-Foreign-Object-Types.html" accesskey="u" rel="up">Defining New Foreign Object Types</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<hr>
|
|
<h4 class="subsection" id="Foreign-Objects-and-Scheme-1"><span>5.5.5 Foreign Objects and Scheme<a class="copiable-link" href="#Foreign-Objects-and-Scheme-1"> ¶</a></span></h4>
|
|
|
|
<p>It is also possible to create foreign objects and object types from
|
|
Scheme, and to access fields of foreign objects from Scheme. For
|
|
example, the file example from the last section could be equivalently
|
|
expressed as:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example-preformatted">(define-module (my-file)
|
|
#:use-module (system foreign-object)
|
|
#:use-module ((oop goops) #:select (make))
|
|
#:export (make-file))
|
|
|
|
(define (finalize-file file)
|
|
(let ((fd (struct-ref file 0)))
|
|
(unless (< fd 0)
|
|
(struct-set! file 0 -1)
|
|
(close-fdes fd))))
|
|
|
|
(define <file>
|
|
(make-foreign-object-type '<file> '(fd)
|
|
#:finalizer finalize-file))
|
|
|
|
(define (make-file fd)
|
|
(make <file> #:fd fd))
|
|
</pre></div>
|
|
|
|
<p>Here we see that the result of <code class="code">make-foreign-object-type</code>, which is
|
|
the equivalent of <code class="code">scm_make_foreign_object_type</code>, is a struct
|
|
vtable. See <a class="xref" href="Vtables.html">Vtables</a>, for more information. To instantiate the
|
|
foreign object, which is really a Guile struct, we use <code class="code">make</code>. (We
|
|
could have used <code class="code">make-struct/no-tail</code>, but as an implementation
|
|
detail, finalizers are attached in the <code class="code">initialize</code> method called
|
|
by <code class="code">make</code>). To access the fields, we use <code class="code">struct-ref</code> and
|
|
<code class="code">struct-set!</code>. See <a class="xref" href="Structure-Basics.html">Structure Basics</a>.
|
|
</p>
|
|
<p>There is a convenience syntax, <code class="code">define-foreign-object-type</code>, that
|
|
defines a type along with a constructor, and getters for the fields. An
|
|
appropriate invocation of <code class="code">define-foreign-object-type</code> for the
|
|
file object type could look like this:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example-preformatted">(use-modules (system foreign-object))
|
|
|
|
(define-foreign-object-type <file>
|
|
make-file
|
|
(fd)
|
|
#:finalizer finalize-file)
|
|
</pre></div>
|
|
|
|
<p>This defines the <code class="code"><file></code> type with one field, a <code class="code">make-file</code>
|
|
constructor, and a getter for the <code class="code">fd</code> field, bound to <code class="code">fd</code>.
|
|
</p>
|
|
<p>Foreign object types are not only vtables but are actually GOOPS
|
|
classes, as hinted at above. See <a class="xref" href="GOOPS.html">GOOPS</a>, for more on Guile’s
|
|
object-oriented programming system. Thus one can define print and
|
|
equality methods using GOOPS:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example-preformatted">(use-modules (oop goops))
|
|
|
|
(define-method (write (file <file>) port)
|
|
;; Assuming existence of the `fd' getter
|
|
(format port "#<<file> ~a>" (fd file)))
|
|
|
|
(define-method (equal? (a <file>) (b <file>))
|
|
(eqv? (fd a) (fd b)))
|
|
</pre></div>
|
|
|
|
<p>One can even sub-class foreign types.
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example-preformatted">(define-class <named-file> (<file>)
|
|
(name #:init-keyword #:name #:init-value #f #:accessor name))
|
|
</pre></div>
|
|
|
|
<p>The question arises of how to construct these values, given that
|
|
<code class="code">make-file</code> returns a plain old <code class="code"><file></code> object. It turns out
|
|
that you can use the GOOPS construction interface, where every field of
|
|
the foreign object has an associated initialization keyword argument.
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example-preformatted">(define* (my-open-file name #:optional (flags O_RDONLY))
|
|
(make <named-file> #:fd (open-fdes name flags) #:name name))
|
|
|
|
(define-method (write (file <named-file>) port)
|
|
(format port "#<<file> ~s ~a>" (name file) (fd file)))
|
|
</pre></div>
|
|
|
|
<p>See <a class="xref" href="Foreign-Objects.html">Foreign Objects</a>, for full documentation on the Scheme interface
|
|
to foreign objects. See <a class="xref" href="GOOPS.html">GOOPS</a>, for more on GOOPS.
|
|
</p>
|
|
<p>As a final note, you might wonder how this system supports encapsulation
|
|
of sensitive values. First, we have to recognize that some facilities
|
|
are essentially unsafe and have global scope. For example, in C, the
|
|
integrity and confidentiality of a part of a program is at the mercy of
|
|
every other part of that program – because any part of the program can
|
|
read and write anything in its address space. At the same time,
|
|
principled access to structured data is organized in C on lexical
|
|
boundaries; if you don’t expose accessors for your object, you trust
|
|
other parts of the program not to work around that barrier.
|
|
</p>
|
|
<p>The situation is not dissimilar in Scheme. Although Scheme’s unsafe
|
|
constructs are fewer in number than in C, they do exist. The
|
|
<code class="code">(system foreign)</code> module can be used to violate confidentiality
|
|
and integrity, and shouldn’t be exposed to untrusted code. Although
|
|
<code class="code">struct-ref</code> and <code class="code">struct-set!</code> are less unsafe, they still
|
|
have a cross-cutting capability of drilling through abstractions.
|
|
Performing a <code class="code">struct-set!</code> on a foreign object slot could cause
|
|
unsafe foreign code to crash. Ultimately, structures in Scheme are
|
|
capabilities for abstraction, and not abstractions themselves.
|
|
</p>
|
|
<p>That leaves us with the lexical capabilities, like constructors and
|
|
accessors. Here is where encapsulation lies: the practical degree to
|
|
which the innards of your foreign objects are exposed is the degree to
|
|
which their accessors are lexically available in user code. If you want
|
|
to allow users to reference fields of your foreign object, provide them
|
|
with a getter. Otherwise you should assume that the only access to your
|
|
object may come from your code, which has the relevant authority, or via
|
|
code with access to cross-cutting <code class="code">struct-ref</code> and such, which also
|
|
has the cross-cutting authority.
|
|
</p>
|
|
</div>
|
|
<hr>
|
|
<div class="nav-panel">
|
|
<p>
|
|
Previous: <a href="Foreign-Object-Memory-Management.html">Foreign Object Memory Management</a>, Up: <a href="Defining-New-Foreign-Object-Types.html">Defining New Foreign Object Types</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|