PageRenderTime 12ms CodeModel.GetById 2ms app.highlight 6ms RepoModel.GetById 2ms app.codeStats 0ms

/trunk/Examples/tcl/class/index.html

#
HTML | 274 lines | 217 code | 57 blank | 0 comment | 0 complexity | 5c90d2a56c2ff3541193c400f4497d56 MD5 | raw file
  1<html>
  2<head>
  3<title>SWIG:Examples:tcl:class</title>
  4</head>
  5
  6<body bgcolor="#ffffff">
  7
  8
  9<tt>SWIG/Examples/tcl/class/</tt>
 10<hr>
 11
 12<H2>Wrapping a simple C++ class</H2>
 13
 14<p>
 15This example illustrates the most primitive form of C++ class wrapping performed
 16by SWIG.  In this case, C++ classes are simply transformed into a collection of
 17C-style functions that provide access to class members.
 18
 19<h2>The C++ Code</h2>
 20
 21Suppose you have some C++ classes described by the following (and admittedly lame) 
 22header file:
 23
 24<blockquote>
 25<pre>
 26/* File : example.h */
 27
 28class Shape {
 29public:
 30  Shape() {
 31    nshapes++;
 32  }
 33  virtual ~Shape() {
 34    nshapes--;
 35  };
 36  double  x, y;   
 37  void    move(double dx, double dy);
 38  virtual double area() = 0;
 39  virtual double perimeter() = 0;
 40  static  int nshapes;
 41};
 42
 43class Circle : public Shape {
 44private:
 45  double radius;
 46public:
 47  Circle(double r) : radius(r) { };
 48  virtual double area();
 49  virtual double perimeter();
 50};
 51
 52class Square : public Shape {
 53private:
 54  double width;
 55public:
 56  Square(double w) : width(w) { };
 57  virtual double area();
 58  virtual double perimeter();
 59};
 60</pre>
 61</blockquote>
 62
 63<h2>The SWIG interface</h2>
 64
 65A simple SWIG interface for this can be built by simply grabbing the header file
 66like this:
 67
 68<blockquote>
 69<pre>
 70/* File : example.i */
 71%module example
 72
 73%{
 74#include "example.h"
 75%}
 76
 77/* Let's just grab the original header file here */
 78%include "example.h"
 79</pre>
 80</blockquote>
 81
 82Note: when creating a C++ extension, you must run SWIG with the <tt>-c++</tt> option like this:
 83<blockquote>
 84<pre>
 85% swig -c++ -tcl example.i
 86</pre>
 87</blockquote>
 88
 89<h2>Some sample Tcl scripts</h2>
 90
 91SWIG performs two forms of C++ wrapping-- a low level interface and a high level widget-like interface.
 92<ul>
 93<li>
 94Click <a href="example1.tcl">here</a> to see a script that calls the C++ functions using the
 95low-level interface.
 96<li>
 97Click <a href="example2.tcl">here</a> to see a the same script written with the high-level
 98interface.
 99</ul>
100
101<h2>Key points</h2>
102
103<ul>
104<li>The low-level C++ interface works like this:
105<p>
106<ul>
107<li>To create a new object, you call a constructor like this:
108
109<blockquote>
110<pre>
111set c [new_Circle 10.0]
112</pre>
113</blockquote>
114
115<p>
116<li>To access member data, a pair of accessor functions are used.
117For example:
118
119<blockquote>
120<pre>
121Shape_x_set $c 15        ;# Set member data
122set x [Shape_x_get $c]   ;# Get member data
123</pre>
124</blockquote>
125
126Note: when accessing member data, the name of the base class must
127be used such as <tt>Shape_x_get</tt>
128
129<p>
130<li>To invoke a member function, you simply do this
131
132<blockquote>
133<pre>
134puts "The area is [Shape_area $c]"
135</pre>
136</blockquote>
137
138<p>
139<li>Type checking knows about the inheritance structure of C++. For example:
140
141<blockquote>
142<pre>
143Shape_area $c       # Works (c is a Shape)
144Circle_area $c      # Works (c is a Circle)
145Square_area $c      # Fails (c is definitely not a Square)
146</pre>
147</blockquote>
148
149<p>
150<li>To invoke a destructor, simply do this
151
152<blockquote>
153<pre>
154delete_Shape $c     # Deletes a shape
155</pre>
156</blockquote>
157
158<p>
159<li>Static member variables are wrapped as C global variables.  For example:
160
161<blockquote>
162<pre>
163set n $Shape_nshapes    # Get a static data member
164set Shapes_nshapes 13   # Set a static data member
165</pre>
166</blockquote>
167
168</ul>
169
170<p>
171<li>The high-level interface works like a Tk widget
172
173<p>
174<ul>
175<li>To create a new object, you call a constructor like this:
176
177<blockquote>
178<pre>
179Circle c 10      # c becomes a name for the Circle object
180</pre>
181</blockquote>
182
183<p>
184<li>To access member data, use cget and configure methods.
185For example:
186
187<blockquote>
188<pre>
189c configure -x 15        ;# Set member data
190set x [c cget -x]        ;# Get member data
191</pre>
192</blockquote>
193
194<p>
195<li>To invoke a member function, you simply do this
196
197<blockquote>
198<pre>
199puts "The area is [c area]"
200</pre>
201</blockquote>
202
203<p>
204<li>To invoke a destructor, simply destroy the object name like this:
205
206<blockquote>
207<pre>
208rename c ""         # c goes away
209</pre>
210</blockquote>
211
212<p>
213<li>Static member variables are wrapped as C global variables.  For example:
214
215<blockquote>
216<pre>
217set n $Shape_nshapes    # Get a static data member
218set Shapes_nshapes 13   # Set a static data member
219</pre>
220</blockquote>
221
222</ul>
223</ul>
224
225<h2>General Comments</h2>
226
227<ul>
228<li>The low-level function interface is much faster than the high-level interface.
229In fact, all the higher level interface does is call functions in the low-level interface.
230
231<p>
232<li>SWIG *does* know how to properly perform upcasting of objects in an inheritance
233hierarchy (including multiple inheritance).  Therefore it is perfectly safe to pass
234an object of a derived class to any function involving a base class.
235
236<p>
237<li>A wide variety of C++ features are not currently supported by SWIG.  Here is the
238short and incomplete list:
239
240<p>
241<ul>
242<li>Overloaded methods and functions.  SWIG wrappers don't know how to resolve name
243conflicts so you must give an alternative name to any overloaded method name using the
244%name directive like this:
245
246<blockquote>
247<pre>
248void foo(int a);  
249%name(foo2) void foo(double a, double b);
250</pre>
251</blockquote>
252
253<p>
254<li>Overloaded operators.  Not supported at all. The only workaround for this is
255to write a helper function. For example:
256
257<blockquote>
258<pre>
259%inline %{
260    Vector *vector_add(Vector *a, Vector *b) {
261          ... whatever ...
262    }
263%}
264</pre>
265</blockquote>
266
267<p>
268<li>Namespaces.  Not supported at all. Won't be supported until SWIG2.0 (if at all).
269
270</ul>
271
272<hr>
273</body>
274</html>