summaryrefslogtreecommitdiff
path: root/Doc/Manual/Mzscheme.html
blob: fadda5fc98949ea27caed73c08cec978005be2eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Hand-written HTML -->
<html>
<head>
<title>SWIG and MzScheme/Racket</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>

<body bgcolor="#ffffff">

<H1><a name="Mzscheme"></a>30 SWIG and MzScheme/Racket</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#MzScheme_nn2">Creating native structures</a>
<li><a href="#MzScheme_simple">Simple example</a>
<li><a href="#MzScheme_external_docs">External documentation</a>
</ul>
</div>
<!-- INDEX -->



<p>
This section contains information on SWIG's support of Racket, formally known as MzScheme.

<H2><a name="MzScheme_nn2"></a>30.1 Creating native structures</H2>


<p>
Example interface file:
</p>

<div class="code">
<pre>
/* define a macro for the struct creation */
%define handle_ptr(TYPE,NAME)
%typemap(argout) TYPE *NAME{
    Scheme_Object *o = SWIG_NewStructFromPtr($1, $*1_mangle);
    SWIG_APPEND_VALUE(o);
}

%typemap(in,numinputs=0) TYPE *NAME (TYPE temp) {
    $1 = &amp;temp;
}
%enddef

/* setup the typemaps for the pointer to an output parameter cntrs */
handle_ptr(struct diag_cntrs, cntrs);
</pre>
</div>

<p>
Then in scheme, you can use regular struct access procedures like
</p>

<div class="code">
<pre>
	; suppose a function created a struct foo as 
	; (define foo (make-diag-cntrs (#x1 #x2 #x3) (make-inspector))
	; Then you can do
	(format "0x~x" (diag-cntrs-field1 foo))
	(format "0x~x" (diag-cntrs-field2 foo))
	;etc...
</pre>
</div>

<H2><a name="MzScheme_simple"></a>30.2 Simple example</H2>


<p>
A few examples are available in the Examples/mzscheme directory.
The code and log of a session using SWIG below should help getting started.
</p>

<p>
C header file:
</p>

<div class="code">
<pre>
// example.h
int fact(int n);
</pre>
</div>

<p>
C source code:
</p>

<div class="code">
<pre>
// File: example.c
#include "example.h"

int fact(int n) {
  if (n &lt; 0) { /* This should probably return an error, but this is simpler */
    return 0;
  }
  if (n == 0) {
    return 1;
  }
  else {
    /* testing for overflow would be a good idea here */
    return n * fact(n-1);
  }
}
</pre>
</div>

<p>
SWIG interface file:
</p>

<div class="code">
<pre>
/* File: example.i */
%module example

%{
#include "example.h"
%}

int fact(int n);
</pre>
</div>

<p>
The session below using the above files is on an OS X machine, but the points to be made are more general. On OS X, libtool is the tool which creates libraries, which are named .dylib, rather than .so on other unixes, or .dll on Windows.
</p>

<div class="shell">
<pre>
% swig -mzscheme -declaremodule example.i
% gcc -c -m32 -o example.o example.c # force 32-bit object file (mzscheme is 32-bit only)
% libtool -dynamic -o libexample.dylib example.o # make it into a library
% ls # what've we got so far?
example.c example.o
example.h example_wrap.c
example.i libexample.dylib*
% mzc --cgc --cc example_wrap.c # compile the wrapping code
% LDFLAGS="-L. -lexample" mzc --ld example_wrap.dylib example_wrap.o # ...and link it
% mzscheme -e '(path-&gt;string (build-path "compiled" "native" (system-library-subpath)))'
"compiled/native/i386-macosx/3m"
% mkdir -p compiled/native/i386-macosx/3m # move the extension library to a magic place
% mv example_wrap.dylib compiled/native/i386-macosx/3m/example_ss.dylib
% mzscheme
Welcome to MzScheme v4.2.4 [3m], Copyright (c) 2004-2010 PLT Scheme Inc.
&gt; (require "example.ss")
&gt; (fact 5)
120
&gt; ^D
% echo 'It works!'
</pre>
</div>


<p>
Some points of interest:
</p>
<ul>
  <li> This is on a 64-bit machine, so we have to include the -m32 option when building the object file
  <li> If you want to declare a scheme module (and you probably do), it's important that you include the -declaremodule option to swig (if you miss this out, it'll appear to work, but fail later).
  <li> Use mzc to compile and then link the wrapped code. You'll probably need to adjust the link flags to refer to the library you're wrapping (you can either do this with an LDFLAGS declaration, as here, or with multiple ++ldf options to mzc).
  <li> Create the directory with path (build-path "compiled" "native" (system-library-subpath)) and move the freshly-generated .dylib to there, changing its name to module-name_ss.dylib. After that, you can REQUIRE the new module with (require "module-name.ss").
  <li> The above requests mzc to create an extension using the CGC garbage-collector. The alternative -- the 3m collector -- has generally better performance, but work is still required for SWIG to emit code which is compatible with it.
</ul>

<H2><a name="MzScheme_external_docs"></a>30.3 External documentation</H2>


<p>
See the <a href="http://docs.racket-lang.org/inside/index.html">C API</a> for more description of using the mechanism for adding extensions. The main documentation is <a href="http://docs.racket-lang.org/">here</a>.
</p>

<p>
Tip: mzc's --vv option is very useful for debugging the inevitable library problems you'll encounter.
</p>

</body>
</html>