-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathtutorial.ht
317 lines (263 loc) · 8.58 KB
/
tutorial.ht
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
SWIG Tutorial
<p>
<img src="images/tutorial.png" alt="Tutorial">
<p>
So you want to get going in a hurry? To illustrate the use of SWIG,
suppose you have some C functions you want added to Tcl, Perl, Python, Java and C#.
Specifically, let's say you have them in a file 'example.c'
<blockquote><pre>
/* File : example.c */
#include <time.h>
double My_variable = 3.0;
int fact(int n) {
if (n <= 1) return 1;
else return n*fact(n-1);
}
int my_mod(int x, int y) {
return (x%y);
}
char *get_time()
{
time_t ltime;
time(&ltime);
return ctime(&ltime);
}
</pre></blockquote>
<h3>Interface file </h3>
Now, in order to add these functions to your favorite language, you need to write an
"interface file" which is the input to SWIG. An interface file for these
C functions might look like this :
<blockquote><pre>
/* example.i */
%module example
%{
/* Put header files here or function declarations like below */
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
%}
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
</pre></blockquote>
<h3> Building a Tcl module </h3>
At the UNIX prompt, type the following (shown for Ubuntu, see the <a href="https://github.com/swig/swig/wiki/FAQ#shared-libraries">SWIG Wiki Shared Libraries FAQ</a> page for help with other operating systems):
<blockquote>
<pre>
unix % swig -tcl example.i
unix % gcc -fPIC -c example.c example_wrap.c \
-I/usr/include/tcl
unix % gcc -shared example.o example_wrap.o -o example.so
unix % tclsh
% load ./example.so example
% puts $My_variable
3.0
% fact 5
120
% my_mod 7 3
1
% get_time
Sun Feb 11 23:01:07 2018
%
</pre></blockquote>
The <tt> swig </tt> command produces a file <a href = "tutorial/example_wrap.html">
<tt> example_wrap.c </tt> </a> that should be compiled and linked with
the rest of the program. In this case, we have built a dynamically
loadable extension that can be loaded into the Tcl interpreter using
the 'load' command.
<h3> Building a Python module </h3>
Turning C code into a Python module is also easy. Simply do the following (shown for Irix, see the <a href="https://github.com/swig/swig/wiki/FAQ#shared-libraries">SWIG Wiki Shared Libraries FAQ</a> page for help with other operating systems):
<blockquote> <pre>
unix % swig -python example.i
unix % gcc -c example.c example_wrap.c \
-I/usr/local/include/python2.7
unix % ld -shared example.o example_wrap.o -o _example.so
</pre> </blockquote>
We can now use the Python module as follows :
<blockquote> <pre>
>>> import example
>>> example.fact(5)
120
>>> example.my_mod(7,3)
1
>>> example.get_time()
'Sun Feb 11 23:01:07 2018'
>>>
</pre>
</blockquote>
<h3> Building a Perl module </h3>
You can also build a Perl5 module as follows (shown for Linux, see the <a href="https://github.com/swig/swig/wiki/FAQ#shared-libraries">SWIG Wiki Shared Libraries FAQ</a> page for help with other operating systems):
<blockquote><pre>
unix % swig -perl5 example.i
unix % gcc -c `perl -MConfig -e 'print join(" ", @Config{qw(ccflags optimize cccdlflags)}, \
"-I$Config{archlib}/CORE")'` example.c example_wrap.c
unix % gcc `perl -MConfig -e 'print $Config{lddlflags}'` example.o example_wrap.o -o example.so
unix % perl
use example;
print $example::My_variable,"\n";
print example::fact(5),"\n";
print example::get_time(),"\n";
<ctrl-d>
3.0
120
Sun Feb 11 23:01:07 2018
unix %
</pre></blockquote>
<h3> Building a Java module </h3>
SWIG will also generate JNI code for accessing C/C++ code from Java. Here is an example building a Java module (shown for Cygwin, see the <a href="https://github.com/swig/swig/wiki/FAQ#shared-libraries">SWIG Wiki Shared Libraries FAQ</a> page for help with other operating systems):
<blockquote><pre>
$ swig -java example.i
$ gcc -c example.c example_wrap.c -I/c/jdk1.3.1/include -I/c/jdk1.3.1/include/win32
$ gcc -shared example.o example_wrap.o -mno-cygwin -Wl,--add-stdcall-alias -o example.dll
$ cat main.java
public class main {
public static void main(String argv[]) {
System.loadLibrary("example");
System.out.println(example.getMy_variable());
System.out.println(example.fact(5));
System.out.println(example.get_time());
}
}
$ javac main.java
$ java main
3.0
120
Mon Mar 4 18:20:31 2002
$
</pre></blockquote>
<h3> Building a C# module </h3>
SWIG will also generate code for accessing C/C++ code from C# using PInvoke. Here is an example building a C# module (shown for Linux, see the <a href="https://github.com/swig/swig/wiki/FAQ#shared-libraries">SWIG Wiki Shared Libraries FAQ</a> page for help with other operating systems). It uses the open source <a href="http://www.mono-project.com/">Mono</a> C# compiler which runs on Windows and most Unix systems, but the Microsoft C# compiler (csc.exe) works equally well on Windows:
<blockquote><pre>
$ swig -csharp example.i
$ gcc -c -fPIC example.c example_wrap.c
$ gcc -shared example.o example_wrap.o -o libexample.so
$ mono-csc -out:runme.exe *.cs
$ cat runme.cs
using System;
public class runme {
static void Main() {
Console.WriteLine(example.My_variable);
Console.WriteLine(example.fact(5));
Console.WriteLine(example.get_time());
}
}
$ ./runme.exe
3
120
Thu Nov 17 21:24:13 2016
$
</pre></blockquote>
<h3> SWIG for the truly lazy </h3>
As it turns out, it is not always necessary to write a special interface
file. If you have a header file, you can often just include it directly in the
SWIG interface. For example:
<blockquote>
<pre>
%module example
%{
/* Includes the header in the wrapper code */
#include "header.h"
%}
/* Parse the header file to generate wrappers */
%include "header.h"
</pre>
</blockquote>
Alternatively, some people might just include SWIG directives in a header
file with conditional compilation. For example:
<blockquote>
<pre>
#ifdef SWIG
%module example
%{
#include "header.h"
%}
#endif
extern int fact(int n);
...
</pre>
</blockquote>
<h3> Running SWIG under Microsoft Windows </h3>
SWIG also works perfectly well under all known 32-bit and 64-bit versions of
Windows. SWIG is typically invoked from
the command prompt and can be used with NMAKE or as custom builds from Visual Studio.
Modules are typically
compiled in the form of a DLL that can be dynamically loaded into Java,
Python, or whatever language you are using.
<h3>That's it (well, more or less)</h3>
That's about everything you need to know to get started. Here's the short checklist :
<ul>
<li> Make sure you specify a module name.
<li> Use ISO C/C++ syntax
<li> Figure out how to compile a shared library module / dynamic link library (may require reading a few man
pages for your compiler).
<li> Relax.
</ul>
<h3>Surely there's more to it...</h3>
The above example is intentionally simple, but the general idea
extends to more complicated C/C++ programming tasks. In fact, it is
important to know that SWIG is a fairly complete C++ compiler with
support for nearly every language feature. This includes
preprocessing, pointers, classes, inheritance, and even C++ templates.
SWIG can also be used to package structures and classes into proxy
classes in the target language---exposing the underlying functionality in a very
natural manner.
<p>
To illustrate, suppose you wanted to wrap the following C++ data structure:
<blockquote>
<pre>
// pair.h. A pair like the STL
namespace std {
template<class T1, class T2> struct pair {
T1 first;
T2 second;
pair() : first(T1()), second(T2()) { };
pair(const T1 &f, const T2 &s) : first(f), second(s) { }
};
}
</pre>
</blockquote>
To wrap with SWIG, you might specify the following interface:
<blockquote>
<pre>
// pair.i - SWIG interface
%module pair
%{
#include "pair.h"
%}
// Ignore the default constructor
%ignore std::pair::pair();
// Parse the original header file
%include "pair.h"
// Instantiate some templates
%template(pairii) std::pair<int,int>;
%template(pairdi) std::pair<double,int>;
</pre>
</blockquote>
Now, compiling for Linux (Python):
<blockquote>
<pre>
$ swig -python -c++ pair.i
$ g++ -c -fPIC pair_wrap.c -I/usr/include/python2.7
$ g++ -shared pair_wrap.o -o _pair.so
$ python
Python 2.7.15 (default, Nov 12 2018, 14:31:15)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pair
>>> a = pair.pairii(3,4)
>>> a.first
3
>>> a.second
4
>>> a.second = 16
>>> a.second
16
>>> b = pair.pairdi(3.5,8)
>>> b.first
3.5
>>> b.second
8
</pre>
</blockquote>