aboutsummaryrefslogtreecommitdiff
path: root/Examples/python/pointer/index.html
blob: ae52eddfd806db9f986335ae0a69280f19921d7c (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
<html>
<head>
<title>SWIG:Examples:python:pointer</title>
</head>

<body bgcolor="#ffffff">

<tt>SWIG/Examples/python/pointer/</tt>
<hr>

<H2>Simple Pointer Handling</H2>

<p>
This example illustrates a couple of techniques for handling
simple pointers in SWIG.  The prototypical example is a C function
that operates on pointers such as this:

<blockquote>
<pre>
void add(int *x, int *y, int *r) { 
    *r = *x + *y;
}
</pre>
</blockquote>

By default, SWIG wraps this function exactly as specified and creates
an interface that expects pointer objects for arguments.  The only
problem is how does one go about creating these objects from a script?

<h2>Possible Solutions</h2>

<ul>
<li>Write some helper functions to explicitly create objects.  For
example:

<blockquote>
<pre>
int *new_int(int ivalue) {
  int *i = (int *) malloc(sizeof(ivalue));
  *i = ivalue;
  return i;
}
int get_int(int *i) {
  return *i;
}

void delete_int(int *i) {
  free(i);
}
</pre>
</blockquote>

Now, in a script you would do this:

<blockquote>
<pre>
a = new_int(37)
b = new_int(42)
c = new_int(0)
add(a,b,c)
r = get_int(c);
print "Result =",r
delete_int(a)
delete_int(b)
delete_int(c)
</pre>
</blockquote>

<p>
<li>Use the SWIG pointer library.  For example, in the interface file 
you would do this:

<blockquote>
<pre>
%include "pointer.i"
</pre>
</blockquote?

and in a script you would do this:

<blockquote>
<pre>
a = ptrcreate("int",37)
b = ptrcreate("int",42)
c = ptrcreate("int")
add(a,b,c)
r = ptrvalue(c)
print "Result =",r
ptrfree(a)
ptrfree(b)
ptrfree(c)
</pre>
</blockquote>

The advantage to using the pointer library is that it unifies some of the helper
functions behind a common set of names.  For example, the same set of functions work
with int, double, float, and other fundamental types.

<p>
<li>Use the SWIG typemap library.  This library allows you to completely
change the way arguments are processed by SWIG.  For example:

<blockquote>
<pre>
%include "typemaps.i"
void add(int *INPUT, int *INPUT, int *OUTPUT);
</pre>
</blockquote>

And in a script:

<blockquote>
<pre>
r = add(37,42)
print "Result =",r
</pre>
</blockquote>
Needless to say, this is substantially easier.

<p>
<li>A final alternative is to use the typemaps library in combination
with the %apply directive.  This allows you to change the names of parameters
that behave as input or output parameters. For example:

<blockquote>
<pre>
%include "typemaps.i"
%apply int *INPUT {int *x, int *y};
%apply int *OUTPUT {int *r};

void add(int *x, int *y, int *r);
void sub(int *x, int *y, int *r);
void mul(int *x, int *y, int *r);
... etc ...
</pre>
</blockquote>

</ul>

<h2>Example</h2>

The following example illustrates the use of these features for pointer
extraction.

<ul>
<li> <a href="example.c">example.c</a>  (C Source)
<li> <a href="example.i">example.i</a>  (SWIG interface)
<li> <a href="runme.py">runme.py</a> (Python Script)
</ul>

<h2>Notes</h2>

<ul>
<li>Since pointers are used for so many different things (arrays, output values,
etc...) the complexity of pointer handling can be as complicated as you want to
make it.

<p>
<li>More documentation on the typemaps.i and pointer.i library files can be
found in the SWIG user manual.  The files also contain documentation.

<p>
<li>The pointer.i library is designed primarily for convenience.  If you
are concerned about performance, you probably want to use a different
approach.

</ul>

<hr>
</body>
</html>