Thousands of changes to correct incorrect HTML. HTML is now valid (transitional 4.01).

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@6074 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2004-08-04 21:28:14 +00:00
commit aa4d1d907d
31 changed files with 6754 additions and 4801 deletions

View file

@ -7,23 +7,23 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>15 Advanced Topics</H1> <H1><a name="Advanced"></a>29 Advanced Topics</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">Creating multi-module packages</a> <li><a href="#Advanced_nn2">Creating multi-module packages</a>
<ul> <ul>
<li><a href="#n3">Runtime support (and potential problems)</a> <li><a href="#Advanced_nn3">Runtime support (and potential problems)</a>
<li><a href="#n4">Why doesn't C++ inheritance work between modules?</a> <li><a href="#Advanced_nn4">Why doesn't C++ inheritance work between modules?</a>
<li><a href="#n5">The SWIG runtime library</a> <li><a href="#Advanced_nn5">The SWIG runtime library</a>
<li><a href="#n6">A few dynamic loading gotchas</a> <li><a href="#Advanced_nn6">A few dynamic loading gotchas</a>
</ul> </ul>
<li><a href="#n7">Dynamic Loading of C++ modules</a> <li><a href="#Advanced_nn7">Dynamic Loading of C++ modules</a>
<li><a href="#n8">Inside the SWIG type-checker</a> <li><a href="#Advanced_nn8">Inside the SWIG type-checker</a>
<ul> <ul>
<li><a href="#n9">Type equivalence</a> <li><a href="#Advanced_nn9">Type equivalence</a>
<li><a href="#n10">Type casting</a> <li><a href="#Advanced_nn10">Type casting</a>
<li><a href="#n11">Why a name based approach?</a> <li><a href="#Advanced_nn11">Why a name based approach?</a>
<li><a href="#n12">Performance of the type-checker</a> <li><a href="#Advanced_nn12">Performance of the type-checker</a>
</ul> </ul>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -32,27 +32,42 @@
<b>Caution: This chapter is under repair!</b> <b>Caution: This chapter is under repair!</b>
<a name="n2"></a><H2>15.1 Creating multi-module packages</H2> <H2><a name="Advanced_nn2"></a>29.1 Creating multi-module packages</H2>
SWIG can be used to create packages consisting of many different modules. However, there are some technical aspects of doing this and techniques for managing the problem.<p> <p>
SWIG can be used to create packages consisting of many different modules. However, there are some technical aspects of doing this and techniques for managing the problem.
</p>
<p>
This chapter doesn't apply to those languages that use static type checking, rather than runtime type checking, such as Java and C#. This chapter doesn't apply to those languages that use static type checking, rather than runtime type checking, such as Java and C#.
<a name="n3"></a><H3>15.1.1 Runtime support (and potential problems)</H3> </p>
<H3><a name="Advanced_nn3"></a>29.1.1 Runtime support (and potential problems)</H3>
<p>
Most SWIG generated modules rely upon a small collection of functions that are used during run-time. Most SWIG generated modules rely upon a small collection of functions that are used during run-time.
These functions are primarily used for pointer type-checking, exception handling, and so on. These functions are primarily used for pointer type-checking, exception handling, and so on.
When you run SWIG, these functions are included in the wrapper file (and declared as static). When you run SWIG, these functions are included in the wrapper file (and declared as static).
If you create a system consisting of many modules, each one will have an identical copy of these runtime libraries :<p> If you create a system consisting of many modules, each one will have an identical copy of these runtime libraries :
<center><img src="ch11.1.png"></center><p> </p>
<center><img src="ch11.1.png" alt="Modules 1-N each have their own identical runtime library"></center>
<p> <p>
This duplication of runtime libraries is usually harmless since there are no namespace conflicts and memory overhead is minimal. However, there is serious problem related to the fact that modules do not share type-information. This is particularly a problem when working with C++ (as described next).<p> This duplication of runtime libraries is usually harmless since there are no namespace conflicts and memory overhead is minimal. However, there is serious problem related to the fact that modules do not share type-information. This is particularly a problem when working with C++ (as described next).
<a name="n4"></a><H3>15.1.2 Why doesn't C++ inheritance work between modules?</H3> </p>
<H3><a name="Advanced_nn4"></a>29.1.2 Why doesn't C++ inheritance work between modules?</H3>
Consider for a moment the following two interface files :<p>
<p> <p>
<blockquote><pre>// File : a.i Consider for a moment the following two interface files :
</p>
<blockquote><pre>
// File : a.i
%module a %module a
// Here is a base class // Here is a base class
@ -76,8 +91,11 @@ public:
}; };
</pre></blockquote> </pre></blockquote>
When compiled into two separate modules, the code does not work properly. In fact, you get a type error such as the following:<p>
<p> <p>
When compiled into two separate modules, the code does not work properly. In fact, you get a type error such as the following:
</p>
<blockquote><pre> <blockquote><pre>
[beazley@guinness shadow]$ <b>python</b> [beazley@guinness shadow]$ <b>python</b>
Python 1.4 (Jan 16 1997) [GCC 2.7.2] Python 1.4 (Jan 16 1997) [GCC 2.7.2]
@ -94,18 +112,26 @@ Traceback (innermost last):
TypeError: Type error in argument 1 of a_foo. Expected _a_p. TypeError: Type error in argument 1 of a_foo. Expected _a_p.
&gt;&gt;&gt; &gt;&gt;&gt;
</pre></blockquote> </pre></blockquote>
<p> <p>
However, from our class definitions we know that "b" is an "a" by inheritance and there should be no type-error. This problem is directly due to the lack of type-sharing between modules. If we look closely at the module modules created here, they look like this :<p> However, from our class definitions we know that "b" is an "a" by inheritance and there should be no type-error. This problem is directly due to the lack of type-sharing between modules. If we look closely at the module modules created here, they look like this :
<center><img src="ch11.2.png"></center><p> </p>
<center><img src="ch11.2.png" alt="a accepts a, b accepts a and b, b accepts b"></center>
<p> <p>
The type information listed shows the acceptable values for various C datatypes. In the "a" module, we see that "a" can only accept instances of itself. In the "b" module, we see that "a" can accept both "a" and "b" instances--which is correct given that a "b" is an "a" by inheritance.<p> The type information listed shows the acceptable values for various C datatypes. In the "a" module, we see that "a" can only accept instances of itself. In the "b" module, we see that "a" can accept both "a" and "b" instances--which is correct given that a "b" is an "a" by inheritance.
</p>
<p> <p>
Unfortunately, this problem is inherent in the method by which SWIG makes modules. When we made the "a" module, we had no idea what derived classes might be used at a later time. However, it's impossible to produce the proper type information until after we know all of the derived classes. A nice problem to be sure, but one that can be fixed by making all modules share a single copy of the SWIG run-time library.<p> Unfortunately, this problem is inherent in the method by which SWIG makes modules. When we made the "a" module, we had no idea what derived classes might be used at a later time. However, it's impossible to produce the proper type information until after we know all of the derived classes. A nice problem to be sure, but one that can be fixed by making all modules share a single copy of the SWIG run-time library.
<a name="n5"></a><H3>15.1.3 The SWIG runtime library</H3> </p>
<H3><a name="Advanced_nn5"></a>29.1.3 The SWIG runtime library</H3>
To reduce overhead and to fix type-handling problems, it is possible to share the SWIG run-time functions between multiple modules. To reduce overhead and to fix type-handling problems, it is possible to share the SWIG run-time functions between multiple modules.
The <a href="#Modules.html">Working with Modules</a> chapter describes this in further detail and how to build the SWIG runtime library. The steps can be summarised as follows: The <a href="Modules.html#Modules">Working with Modules</a> chapter describes this in further detail and how to build the SWIG runtime library. The steps can be summarised as follows:
<ul> <ul>
<li> Build the SWIG run-time libraries. </li> <li> Build the SWIG run-time libraries. </li>
@ -113,24 +139,33 @@ The <a href="#Modules.html">Working with Modules</a> chapter describes this in f
<li> Build SWIG modules by linking against the appropriate runtime libraries. </li> <li> Build SWIG modules by linking against the appropriate runtime libraries. </li>
</ul> </ul>
When completed you should now end up with a collection of modules like this:<p>
<center><img src="ch11.3.png"></center><p>
<p> <p>
<p> When completed you should now end up with a collection of modules like this:
In this configuration, the runtime library manages all datatypes and other information between modules. This management process is dynamic in nature--when new modules are loaded, they contribute information to the run-time system. In the C++ world, one could incrementally load classes as needed. As this process occurs, type information is updated and base-classes learn about derived classes as needed.<p> </p>
<center><img src="ch11.3.png" alt="Modules 1-N using single runtime"></center>
<p> <p>
In this configuration, the runtime library manages all datatypes and other information between modules. This management process is dynamic in nature--when new modules are loaded, they contribute information to the run-time system. In the C++ world, one could incrementally load classes as needed. As this process occurs, type information is updated and base-classes learn about derived classes as needed.
</p>
<p>
<b>Compatibility Note:</b> In SWIG-1.3.19 and earlier releases, SWIG built the runtime libraries by default and attempted to install them with the SWIG installation. This had numerous limitations, not least, the version of the target language was tied to what was detected at installation time and would not necessarily be the version the user required. <b>Compatibility Note:</b> In SWIG-1.3.19 and earlier releases, SWIG built the runtime libraries by default and attempted to install them with the SWIG installation. This had numerous limitations, not least, the version of the target language was tied to what was detected at installation time and would not necessarily be the version the user required.
</p>
<a name="n6"></a><H3>15.1.4 A few dynamic loading gotchas</H3> <H3><a name="Advanced_nn6"></a>29.1.4 A few dynamic loading gotchas</H3>
When working with dynamic loading, it is critical to check that only one copy of the run-time library is being loaded into the system. When working with <tt>.a</tt> library files, problems can sometimes occur so there are a few approaches to the problem.<p>
<p> <p>
1. Rebuild the scripting language executable with the SWIG runtime library attached to it. This is actually, fairly easy to do using SWIG. For example :<p> When working with dynamic loading, it is critical to check that only one copy of the run-time library is being loaded into the system. When working with <tt>.a</tt> library files, problems can sometimes occur so there are a few approaches to the problem.
</p>
<p> <p>
<blockquote><pre>%module mytclsh 1. Rebuild the scripting language executable with the SWIG runtime library attached to it. This is actually, fairly easy to do using SWIG. For example :
</p>
<blockquote><pre>
%module mytclsh
%{ %{
static void *__embedfunc(void *a) { return a}; static void *__embedfunc(void *a) { return a};
@ -138,31 +173,44 @@ static void *__embedfunc(void *a) { return a};
void *__embedfunc(void *); void *__embedfunc(void *);
%include tclsh.i %include tclsh.i
</pre></blockquote> </pre></blockquote>
<p> <p>
Now, assuming you have built the <a href="Modules.html">runtime library</a> as <tt>swigruntcl</tt>, run SWIG and compile as follows:<p> Now, assuming you have built the <a href="Modules.html#Modules">runtime library</a> as <tt>swigruntcl</tt>, run SWIG and compile as follows:
<p> </p>
<blockquote><pre> <blockquote><pre>
% <b>swig -c -tcl mytclsh.i</b> % <b>swig -c -tcl mytclsh.i</b>
% <b>gcc mytclsh_wrap.c -I/usr/local/include -L/usr/local/lib -ltcl -lswigruntcl -ldl -lm \ % <b>gcc mytclsh_wrap.c -I/usr/local/include -L/usr/local/lib -ltcl -lswigruntcl -ldl -lm \
-o tclsh</b> -o tclsh</b>
</pre></blockquote> </pre></blockquote>
This produces a new executable "<tt>tclsh</tt>" that contains a copy of the SWIG runtime library. The weird <tt>__embedfunc()</tt> function is needed to force the functions in the runtime library to be included in the final executable.<p>
<p> <p>
To make new dynamically loadable SWIG modules, simply compile as follows :<p> This produces a new executable "<tt>tclsh</tt>" that contains a copy of the SWIG runtime library. The weird <tt>__embedfunc()</tt> function is needed to force the functions in the runtime library to be included in the final executable.
</p>
<p> <p>
To make new dynamically loadable SWIG modules, simply compile as follows :
</p>
<blockquote><pre> <blockquote><pre>
% <b>swig -c -tcl example.i</b> % <b>swig -c -tcl example.i</b>
% <b>gcc -c example_wrap.c -I/usr/local/include</b> % <b>gcc -c example_wrap.c -I/usr/local/include</b>
% <b>ld -shared example_wrap.o -o example.so</b> % <b>ld -shared example_wrap.o -o example.so</b>
</pre></blockquote> </pre></blockquote>
<p>
Linking against the <tt>swigruntcl</tt> library is no longer necessary as all of the functions are now included in the <tt>tclsh</tt> executable and will be resolved when your module is loaded. Linking against the <tt>swigruntcl</tt> library is no longer necessary as all of the functions are now included in the <tt>tclsh</tt> executable and will be resolved when your module is loaded.
However, some operating systems, like Windows, will still require linking with the libraries so that there are no unresolved symbols.<p> However, some operating systems, like Windows, will still require linking with the libraries so that there are no unresolved symbols.
</p>
<p> <p>
2. Using shared library versions of the runtime library<p> 2. Using shared library versions of the runtime library
</p>
<p> <p>
If supported on your machine, the runtime libraries will be built as shared libraries (for example a <tt>.so</tt>, <tt>.sl</tt>, or .<tt>dll</tt> suffix). To compile using the runtime libraries, your link process should look something like this:<p> If supported on your machine, the runtime libraries will be built as shared libraries (for example a <tt>.so</tt>, <tt>.sl</tt>, or .<tt>dll</tt> suffix). To compile using the runtime libraries, your link process should look something like this:
</p>
<blockquote><pre> <blockquote><pre>
% <b>ld -shared example_wrap.o -o libexample.so</b> # Irix % <b>ld -shared example_wrap.o -o libexample.so</b> # Irix
@ -172,33 +220,58 @@ If supported on your machine, the runtime libraries will be built as shared libr
/link /LIBPATH:PathToRuntimeLibrary /LIBPATH:c:\Tcl\lib</b> # Windows VC++ /link /LIBPATH:PathToRuntimeLibrary /LIBPATH:c:\Tcl\lib</b> # Windows VC++
</pre></blockquote> </pre></blockquote>
<p>
In order for the <tt>libexample.so</tt> library to work, it needs to be placed in a location where the dynamic loader can find it. In order for the <tt>libexample.so</tt> library to work, it needs to be placed in a location where the dynamic loader can find it.
Typically this is a system library directory (eg. <tt>/usr/local/lib</tt> or <tt>/usr/lib</tt>).<p> Typically this is a system library directory (eg. <tt>/usr/local/lib</tt> or <tt>/usr/lib</tt>).
</p>
<p> <p>
When running with the shared libary version, you may get error messages such as the following:<p> When running with the shared libary version, you may get error messages such as the following:
</p>
<blockquote><pre>
Unable to locate libexample.so
</pre></blockquote>
<p> <p>
<blockquote><pre>Unable to locate libexample.so</pre></blockquote>
This indicates that the loader was unable to find the shared libary at run-time. This indicates that the loader was unable to find the shared libary at run-time.
To find shared libaries, the loader looks through a collection of predetermined paths. To find shared libaries, the loader looks through a collection of predetermined paths.
If the shared library file is not in any of these directories, it results in an error. If the shared library file is not in any of these directories, it results in an error.
On most machines, you can change the loader search path by changing the path (Windows) or environment variable <tt>LD_LIBRARY_PATH</tt> (Unix), e.g.<p> On most machines, you can change the loader search path by changing the path (Windows) or environment variable <tt>LD_LIBRARY_PATH</tt> (Unix), e.g.
</p>
<blockquote><pre>
% <b>setenv LD_LIBRARY_PATH .:/home/beazley/packages/lib</b>
</pre></blockquote>
<p> <p>
<blockquote><pre>% <b>setenv LD_LIBRARY_PATH .:/home/beazley/packages/lib</b></pre></blockquote> A somewhat better approach is to link your module with the proper path encoded. This is typically done using the `<tt>-rpath</tt>' or `<tt>-R</tt>' option to your linker on Unix (see the man page). For example:
A somewhat better approach is to link your module with the proper path encoded. This is typically done using the `<tt>-rpath</tt>' or `<tt>-R</tt>' option to your linker on Unix (see the man page). For example:<p> </p>
<p>
<blockquote><pre>% <b>ld -shared example_wrap.o example.o -rpath /home/beazley/packages/lib \ <blockquote><pre>
% <b>ld -shared example_wrap.o example.o -rpath /home/beazley/packages/lib \
-L/home/beazley/packages/lib -lswigruntcl.so -o example.so</b> -L/home/beazley/packages/lib -lswigruntcl.so -o example.so</b>
</pre></blockquote> </pre></blockquote>
The <tt>-rpath</tt> option encodes the location of shared libraries into your modules and gets around having to set the <tt>LD_LIBRARY_PATH</tt> variable.<p>
<p> <p>
If all else fails, pull up the man pages for your linker and start playing around.<p> The <tt>-rpath</tt> option encodes the location of shared libraries into your modules and gets around having to set the <tt>LD_LIBRARY_PATH</tt> variable.
<a name="n7"></a><H2>15.2 Dynamic Loading of C++ modules</H2> </p>
<p>
If all else fails, pull up the man pages for your linker and start playing around.
</p>
<H2><a name="Advanced_nn7"></a>29.2 Dynamic Loading of C++ modules</H2>
Dynamic loading of C++ modules presents a special problem for many systems. This is because C++ modules often need additional supporting code for proper initialization and operation. Static constructors are also a bit of a problem.<p>
<p> <p>
While the process of building C++ modules is, by no means, and exact science, here are a few rules of thumb to follow :<p> Dynamic loading of C++ modules presents a special problem for many systems. This is because C++ modules often need additional supporting code for proper initialization and operation. Static constructors are also a bit of a problem.
</p>
<p> <p>
While the process of building C++ modules is, by no means, and exact science, here are a few rules of thumb to follow :
</p>
<ul> <ul>
<li>Don't use static constructors if at all possible (not always avoidable). <li>Don't use static constructors if at all possible (not always avoidable).
<li>Try linking your module with the C++ compiler using a command like `c++ -shared'. This often solves alot of problems. <li>Try linking your module with the C++ compiler using a command like `c++ -shared'. This often solves alot of problems.
@ -206,113 +279,164 @@ While the process of building C++ modules is, by no means, and exact science, he
<li>Read the compiler and linker man pages over and over until you have them memorized (this may not help in some cases however). <li>Read the compiler and linker man pages over and over until you have them memorized (this may not help in some cases however).
<li>Search articles on Usenet, particularly in <tt>comp.lang.tcl</tt>, <tt>comp.lang.perl</tt>, <tt>comp.lang.python</tt> and <tt>comp.lang.ruby</tt>. Building C++ modules is a common problem. <li>Search articles on Usenet, particularly in <tt>comp.lang.tcl</tt>, <tt>comp.lang.perl</tt>, <tt>comp.lang.python</tt> and <tt>comp.lang.ruby</tt>. Building C++ modules is a common problem.
</ul> </ul>
<p> <p>
The SWIG distribution contains some additional documentation about C++ modules in the Doc directory as well.<p> The SWIG distribution contains some additional documentation about C++ modules in the Doc directory as well.
<a name="n8"></a><H2>15.3 Inside the SWIG type-checker</H2> </p>
<H2><a name="Advanced_nn8"></a>29.3 Inside the SWIG type-checker</H2>
The SWIG runtime type-checker plays a critical role in the correct operation of SWIG modules. It not only checks the validity of pointer types, but also manages C++ inheritance, and performs proper type-casting of pointers when necessary. This section provides some insight into what it does, how it works, and why it is the way it is.<p>
<a name="n9"></a><H3>15.3.1 Type equivalence</H3>
SWIG uses a name-based approach to managing pointer datatypes. For example, if you are using a pointer like "<tt>double *</tt>", the type-checker will look for a particular string representation of that datatype such as "<tt>_double_p</tt>". If no match is found, a type-error is reported.<p>
<p> <p>
However, the matching process is complicated by the fact that datatypes may use a variety of different names. For example, the following declarations<p> The SWIG runtime type-checker plays a critical role in the correct operation of SWIG modules. It not only checks the validity of pointer types, but also manages C++ inheritance, and performs proper type-casting of pointers when necessary. This section provides some insight into what it does, how it works, and why it is the way it is.
</p>
<H3><a name="Advanced_nn9"></a>29.3.1 Type equivalence</H3>
<p> <p>
<blockquote><pre>typedef double Real; SWIG uses a name-based approach to managing pointer datatypes. For example, if you are using a pointer like "<tt>double *</tt>", the type-checker will look for a particular string representation of that datatype such as "<tt>_double_p</tt>". If no match is found, a type-error is reported.
</p>
<p>
However, the matching process is complicated by the fact that datatypes may use a variety of different names. For example, the following declarations
</p>
<blockquote><pre>
typedef double Real;
typedef Real * RealPtr; typedef Real * RealPtr;
typedef double Float; typedef double Float;
</pre></blockquote> </pre></blockquote>
define two sets of equivalent types :<p>
<p>
<blockquote><pre>{double, Real, Float}
{RealPtr, Real *}
<p>
define two sets of equivalent types :
</p>
<blockquote><pre>
{double, Real, Float}
{RealPtr, Real *}
</pre></blockquote> </pre></blockquote>
All of the types in each set are freely interchangable and the type-checker knows about the relationships by managing a table of equivalences such as the following :<p>
<p>
All of the types in each set are freely interchangable and the type-checker knows about the relationships by managing a table of equivalences such as the following :
</p>
<blockquote><pre> <blockquote><pre>
double =&gt; { Real, Float } double =&gt; { Real, Float }
Real =&gt; { double, Float } Real =&gt; { double, Float }
Float =&gt; { double, Real } Float =&gt; { double, Real }
RealPtr =&gt; { Real * } RealPtr =&gt; { Real * }
Real * =&gt; { RealPtr } Real * =&gt; { RealPtr }
</pre></blockquote> </pre></blockquote>
<p>
When you declare a function such as the following :<p>
<p>
<blockquote><pre>void foo(Real *a);
</pre></blockquote>
SWIG first checks to see if the argument passed is a "<tt>Real *</tt>". If not, it checks to see if it is any of the other equivalent types (<tt>double *</tt>, <tt>RealPtr</tt>, <tt>Float *</tt>). If so, the value is accepted and no error occurs.<p>
<p> <p>
Derived versions of the various datatypes are also legal. For example, if you had a function like this,<p> When you declare a function such as the following :
<p> </p>
<blockquote><pre>void bar(Float ***a);
<blockquote><pre>
void foo(Real *a);
</pre></blockquote> </pre></blockquote>
The type-checker will accept pointers of type <tt>double ***</tt> and <tt>Real ***.</tt> However, the type-checker does not always capture the full-range of possibilities. For example, a datatype of `<tt>RealPtr **</tt>' is equivalent to a `<tt>Float ***</tt>' but would be flagged as a type error. If you encounter this kind of problem, you can manually force SWIG to make an equivalence as follows:<p>
<p> <p>
<blockquote><pre>// Tell the type checker that `Float_ppp' and `RealPtr_pp' are equivalent. SWIG first checks to see if the argument passed is a "<tt>Real *</tt>". If not, it checks to see if it is any of the other equivalent types (<tt>double *</tt>, <tt>RealPtr</tt>, <tt>Float *</tt>). If so, the value is accepted and no error occurs.
</p>
<p>
Derived versions of the various datatypes are also legal. For example, if you had a function like this,
</p>
<blockquote><pre>
void bar(Float ***a);
</pre></blockquote>
<p>
The type-checker will accept pointers of type <tt>double ***</tt> and <tt>Real ***.</tt> However, the type-checker does not always capture the full-range of possibilities. For example, a datatype of `<tt>RealPtr **</tt>' is equivalent to a `<tt>Float ***</tt>' but would be flagged as a type error. If you encounter this kind of problem, you can manually force SWIG to make an equivalence as follows:
</p>
<blockquote><pre>
// Tell the type checker that `Float_ppp' and `RealPtr_pp' are equivalent.
%init %{ %init %{
SWIG_RegisterMapping("Float_ppp","RealPtr_pp",0); SWIG_RegisterMapping("Float_ppp","RealPtr_pp",0);
%} %}
</pre></blockquote> </pre></blockquote>
Doing this should hardly ever be necessary (I have never encountered a case where this was necessary), but if all else fails, you can force the run-time type checker into doing what you want.<p>
<p> <p>
Type-equivalence of C++ classes is handled in a similar manner, but is encoded in a manner to support inheritance. For example, consider the following classes hierarchy :<p> Doing this should hardly ever be necessary (I have never encountered a case where this was necessary), but if all else fails, you can force the run-time type checker into doing what you want.
</p>
<p> <p>
<blockquote><pre>class A { }; Type-equivalence of C++ classes is handled in a similar manner, but is encoded in a manner to support inheritance. For example, consider the following classes hierarchy :
</p>
<blockquote><pre>
class A { };
class B : public A { }; class B : public A { };
class C : public B { }; class C : public B { };
class D {}; class D {};
class E : public C, public D {}; class E : public C, public D {};
</pre></blockquote> </pre></blockquote>
The type-checker encodes this into the following sets :<p>
<p> <p>
<blockquote><pre>A =&gt; { B, C, E } "B isa A, C isa A, E isa A" The type-checker encodes this into the following sets :
</p>
<blockquote><pre>
A =&gt; { B, C, E } "B isa A, C isa A, E isa A"
B =&gt; { C, E } "C isa B, E isa B" B =&gt; { C, E } "C isa B, E isa B"
C =&gt; { E } "E isa C" C =&gt; { E } "E isa C"
D =&gt; { E } "E isa D" D =&gt; { E } "E isa D"
E =&gt; { } E =&gt; { }
</pre></blockquote> </pre></blockquote>
The encoding reflects the class hierarchy. For example, any object of type "A" will also accept objects of type B,C, and E because these are all derived from A. However, it is not legal to go the other way. For example, a function operating on a object from class E will not accept an object from class A.<p>
<a name="n10"></a><H3>15.3.2 Type casting</H3>
When working with C++ classes, SWIG needs to perform proper typecasting between derived and base classes. This is particularly important when working with multiple inheritance. To do this, conversion functions are created such as the following :<p>
<p> <p>
<blockquote><pre>void *EtoA(void *ptr) { The encoding reflects the class hierarchy. For example, any object of type "A" will also accept objects of type B,C, and E because these are all derived from A. However, it is not legal to go the other way. For example, a function operating on a object from class E will not accept an object from class A.
</p>
<H3><a name="Advanced_nn10"></a>29.3.2 Type casting</H3>
<p>
When working with C++ classes, SWIG needs to perform proper typecasting between derived and base classes. This is particularly important when working with multiple inheritance. To do this, conversion functions are created such as the following :
</p>
<blockquote><pre>
void *EtoA(void *ptr) {
E *in = (E *) ptr; E *in = (E *) ptr;
A *out = (A *) in; // Cast using C++ A *out = (A *) in; // Cast using C++
return (void *) out; return (void *) out;
} }
</pre></blockquote> </pre></blockquote>
All pointers are internally represented as void *, but conversion functions are always invoked when pointer values are converted between base and derived classes in a C++ class hierarchy.<p>
<a name="n11"></a><H3>15.3.3 Why a name based approach?</H3>
SWIG uses a name-based approach to type-checking for a number of reasons :<p>
<p> <p>
All pointers are internally represented as void *, but conversion functions are always invoked when pointer values are converted between base and derived classes in a C++ class hierarchy.
</p>
<H3><a name="Advanced_nn11"></a>29.3.3 Why a name based approach?</H3>
<p>
SWIG uses a name-based approach to type-checking for a number of reasons :
</p>
<ul> <ul>
<li>One of SWIG's main uses is code development and debugging. In this environment, the type name of an object turns out to be a useful piece of information in tracking down problems. <li>One of SWIG's main uses is code development and debugging. In this environment, the type name of an object turns out to be a useful piece of information in tracking down problems.
<li>In languages like Perl, the name of a datatype is used to determine things like packages and classes. By using datatype names we get a natural mapping between C and Perl. <li>In languages like Perl, the name of a datatype is used to determine things like packages and classes. By using datatype names we get a natural mapping between C and Perl.
<li>I believe using the original names of datatypes is more intuitive than munging them into something completely different. <li>I believe using the original names of datatypes is more intuitive than munging them into something completely different.
</ul> </ul>
<p> <p>
An alternative to a name based scheme would be to generate type-signatures based on the structure of a datatype. Such a scheme would result in perfect type-checking, but I think it would also result in a very confusing scripting language module. For this reason, I see SWIG sticking with the name-based approach--at least for the foreseeable future. <p> An alternative to a name based scheme would be to generate type-signatures based on the structure of a datatype. Such a scheme would result in perfect type-checking, but I think it would also result in a very confusing scripting language module. For this reason, I see SWIG sticking with the name-based approach--at least for the foreseeable future.
<a name="n12"></a><H3>15.3.4 Performance of the type-checker</H3> </p>
<H3><a name="Advanced_nn12"></a>29.3.4 Performance of the type-checker</H3>
The type-checker performs the following steps when matching a datatype :<p>
<p> <p>
The type-checker performs the following steps when matching a datatype :
</p>
<dl> <dl>
<dt>1. Check a pointer against the type supplied in the original C declaration. If there is a perfect match, we're done. <dt>1. Check a pointer against the type supplied in the original C declaration. If there is a perfect match, we're done.
@ -321,14 +445,16 @@ The type-checker performs the following steps when matching a datatype :<p>
<dt>4. If not found, report an error. <dt>4. If not found, report an error.
</dl> </dl>
<p>
Most well-structured C codes will find an exact match on the first attempt, providing the best possible performance. For C++ codes, it is quite common to be passing various objects of a common base-class around between functions. When base-class functions are invoked, it almost always results in a miscompare (because the type-checker is looking for the base-type). In this case, we drop down to a small cache of recently used datatypes. If we've used a pointer of the same type recently, it will be in the cache and we can match against it. For tight loops, this results in about 10-15% overhead over finding a match on the first try. Finally, as a last resort, we need to search the internal pointer tables for a match. This involves a combination of hash table lookup and linear search. If a match is found, it is placed into the cache and the result returned. If not, we finally report a type-mismatch.<p>
<p>
As a rule of thumb, C++ programs require somewhat more processing than C programs, but this seems to be avoidable. Also, keep in mind that performance penalties in the type-checker don't necessarily translate into big penalties in the overall application. Performance is most greatly affected by the efficiency of the target scripting language and the types of operations your C code is performing.<p>
<p>
<p>
<p><hr> <p>
Most well-structured C codes will find an exact match on the first attempt, providing the best possible performance. For C++ codes, it is quite common to be passing various objects of a common base-class around between functions. When base-class functions are invoked, it almost always results in a miscompare (because the type-checker is looking for the base-type). In this case, we drop down to a small cache of recently used datatypes. If we've used a pointer of the same type recently, it will be in the cache and we can match against it. For tight loops, this results in about 10-15% overhead over finding a match on the first try. Finally, as a last resort, we need to search the internal pointer tables for a match. This involves a combination of hash table lookup and linear search. If a match is found, it is placed into the cache and the result returned. If not, we finally report a type-mismatch.
</p>
<p>
As a rule of thumb, C++ programs require somewhat more processing than C programs, but this seems to be avoidable. Also, keep in mind that performance penalties in the type-checker don't necessarily translate into big penalties in the overall application. Performance is most greatly affected by the efficiency of the target scripting language and the types of operations your C code is performing.
</p>
<hr>
<address>SWIG 1.3 - Last Modified : July 9, 2004</address> <address>SWIG 1.3 - Last Modified : July 9, 2004</address>
</body> </body>

View file

@ -5,22 +5,22 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>7 Argument Handling</H1> <H1><a name="Arguments"></a>9 Argument Handling</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">The typemaps.i library</a> <li><a href="#Arguments_nn2">The typemaps.i library</a>
<ul> <ul>
<li><a href="#n3">Introduction</a> <li><a href="#Arguments_nn3">Introduction</a>
<li><a href="#n4">Input parameters</a> <li><a href="#Arguments_nn4">Input parameters</a>
<li><a href="#n5">Output parameters</a> <li><a href="#Arguments_nn5">Output parameters</a>
<li><a href="#n6">Input/Output parameters</a> <li><a href="#Arguments_nn6">Input/Output parameters</a>
<li><a href="#n7">Using different names</a> <li><a href="#Arguments_nn7">Using different names</a>
</ul> </ul>
<li><a href="#n8">Applying constraints to input values</a> <li><a href="#Arguments_nn8">Applying constraints to input values</a>
<ul> <ul>
<li><a href="#n9">Simple constraint example</a> <li><a href="#Arguments_nn9">Simple constraint example</a>
<li><a href="#n10">Constraint methods</a> <li><a href="#Arguments_nn10">Constraint methods</a>
<li><a href="#n11">Applying constraints to new datatypes</a> <li><a href="#Arguments_nn11">Applying constraints to new datatypes</a>
</ul> </ul>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -39,20 +39,21 @@ However, in certain applications it is desirable to change SWIG's
handling of a specific datatype. For example, you might want to handling of a specific datatype. For example, you might want to
return multiple values through the arguments of a function. This chapter return multiple values through the arguments of a function. This chapter
describes some of the techniques for doing this. describes some of the techniques for doing this.
</p>
<a name="n2"></a><H2>7.1 The typemaps.i library</H2> <H2><a name="Arguments_nn2"></a>9.1 The typemaps.i library</H2>
This section describes the <tt>typemaps.i</tt> library file--commonly used to This section describes the <tt>typemaps.i</tt> library file--commonly used to
change certain properties of argument conversion. change certain properties of argument conversion.
<a name="n3"></a><H3>7.1.1 Introduction</H3> <H3><a name="Arguments_nn3"></a>9.1.1 Introduction</H3>
Suppose you had a C function like this: Suppose you had a C function like this:
<p> <blockquote><pre>
<blockquote><pre>void add(double a, double b, double *result) { void add(double a, double b, double *result) {
*result = a + b; *result = a + b;
} }
</pre></blockquote> </pre></blockquote>
@ -62,13 +63,15 @@ From reading the source code, it is clear that the function is storing
a value in the <tt>double *result</tt> parameter. However, since SWIG a value in the <tt>double *result</tt> parameter. However, since SWIG
does not examine function bodies, it has no way to know that this is does not examine function bodies, it has no way to know that this is
the underlying behavior. the underlying behavior.
</p>
<p> <p>
One way to deal with this is to use the One way to deal with this is to use the
<tt>typemaps.i</tt> library file and write interface code like this: <tt>typemaps.i</tt> library file and write interface code like this:
</p>
<p> <blockquote><pre>
<blockquote><pre>// Simple example using typemaps // Simple example using typemaps
%module example %module example
%include "typemaps.i" %include "typemaps.i"
@ -76,22 +79,23 @@ One way to deal with this is to use the
extern void add(double a, double b, double *result); extern void add(double a, double b, double *result);
</pre></blockquote> </pre></blockquote>
<p>
The <tt>%apply</tt> directive tells SWIG that you are going to apply The <tt>%apply</tt> directive tells SWIG that you are going to apply
a special type handling rule to a type. The "<tt>double *OUTPUT</tt>" specification is the a special type handling rule to a type. The "<tt>double *OUTPUT</tt>" specification is the
name of a rule that defines how to return an output value from an argument of type name of a rule that defines how to return an output value from an argument of type
<tt>double *</tt>. This rule gets applied to all of the datatypes <tt>double *</tt>. This rule gets applied to all of the datatypes
listed in curly braces-- in this case "<tt>double *result</tt>".<p> listed in curly braces-- in this case "<tt>double *result</tt>".</p>
<p> <p>
When the resulting module is created, you can now use the function When the resulting module is created, you can now use the function
like this (shown for Python): like this (shown for Python):
</p>
<p>
<blockquote><pre> <blockquote><pre>
>>> a = add(3,4) &gt;&gt;&gt; a = add(3,4)
>>> print a &gt;&gt;&gt; print a
7 7
>>> &gt;&gt;&gt;
</pre></blockquote> </pre></blockquote>
In this case, you can see how the output value normally returned in In this case, you can see how the output value normally returned in
@ -103,8 +107,8 @@ since it is no longer necessary to manufacture a special <tt>double
<p> <p>
Once a typemap has been applied to a type, it stays in effect for all future occurrences Once a typemap has been applied to a type, it stays in effect for all future occurrences
of the type and name. For example, you could write the following: of the type and name. For example, you could write the following:
</p>
<p>
<blockquote><pre> <blockquote><pre>
%module example %module example
%include "typemaps.i" %include "typemaps.i"
@ -122,6 +126,7 @@ In this case, the <tt>double *OUTPUT</tt> rule is applied to all of the function
<p> <p>
Typemap transformations can even be extended to multiple return values. Typemap transformations can even be extended to multiple return values.
For example, consider this code: For example, consider this code:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -136,12 +141,12 @@ void getwinsize(int winid, int *width, int *height);
In this case, the function returns multiple values, allowing it to be used like this: In this case, the function returns multiple values, allowing it to be used like this:
<blockquote><pre> <blockquote><pre>
>>> w,h = genwinsize(wid) &gt;&gt;&gt; w,h = genwinsize(wid)
>>> print w &gt;&gt;&gt; print w
400 400
>>> print h &gt;&gt;&gt; print h
300 300
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
@ -149,8 +154,10 @@ In this case, the function returns multiple values, allowing it to be used like
It should also be noted that although the <tt>%apply</tt> directive is It should also be noted that although the <tt>%apply</tt> directive is
used to associate typemap rules to datatypes, you can also use the used to associate typemap rules to datatypes, you can also use the
rule names directly in arguments. For example, you could write this: rule names directly in arguments. For example, you could write this:
</p>
<blockquote><pre>// Simple example using typemaps <blockquote><pre>
// Simple example using typemaps
%module example %module example
%include "typemaps.i" %include "typemaps.i"
@ -166,12 +173,13 @@ else. To clear a typemap, the <tt>%clear</tt> directive should be used. For e
</pre> </pre>
</blockquote> </blockquote>
<a name="n4"></a><H3>7.1.2 Input parameters</H3> <H3><a name="Arguments_nn4"></a>9.1.2 Input parameters</H3>
<p> <p>
The following typemaps instruct SWIG that a pointer really only holds a single The following typemaps instruct SWIG that a pointer really only holds a single
input value: input value:
</p>
<blockquote><pre> <blockquote><pre>
int *INPUT int *INPUT
@ -195,29 +203,33 @@ double add(double *a, double *b) {
Now, consider this SWIG interface: Now, consider this SWIG interface:
<p> <blockquote><pre>
<blockquote><pre>%module example %module example
%include "typemaps.i" %include "typemaps.i"
... ...
extern double add(double *INPUT, double *INPUT); extern double add(double *INPUT, double *INPUT);
</pre></blockquote> </pre></blockquote>
When the function is used in the scripting language interpreter, it will work like this:
<p> <p>
When the function is used in the scripting language interpreter, it will work like this:
</p>
<blockquote><pre> <blockquote><pre>
result = add(3,4) result = add(3,4)
</pre></blockquote> </pre></blockquote>
<a name="n5"></a><H3>7.1.3 Output parameters</H3> <H3><a name="Arguments_nn5"></a>9.1.3 Output parameters</H3>
<p>
The following typemap rules tell SWIG that pointer is the output value of a The following typemap rules tell SWIG that pointer is the output value of a
function. When used, you do not need to supply the argument when function. When used, you do not need to supply the argument when
calling the function. Instead, one or more output values are returned. calling the function. Instead, one or more output values are returned.
</p>
<p> <blockquote><pre>
<blockquote><pre>int *OUTPUT int *OUTPUT
short *OUTPUT short *OUTPUT
long *OUTPUT long *OUTPUT
unsigned int *OUTPUT unsigned int *OUTPUT
@ -227,18 +239,20 @@ double *OUTPUT
float *OUTPUT float *OUTPUT
</pre></blockquote> </pre></blockquote>
These methods can be used as shown in an earlier example. For example, if you have this C function :<p>
<p> <p>
<blockquote><pre>void add(double a, double b, double *c) { These methods can be used as shown in an earlier example. For example, if you have this C function :</p>
<blockquote><pre>
void add(double a, double b, double *c) {
*c = a+b; *c = a+b;
} }
</pre></blockquote> </pre></blockquote>
<p> <p>
A SWIG interface file might look like this :<p> A SWIG interface file might look like this :</p>
<p> <blockquote><pre>
<blockquote><pre>%module example %module example
%include "typemaps.i" %include "typemaps.i"
... ...
extern void add(double a, double b, double *OUTPUT); extern void add(double a, double b, double *OUTPUT);
@ -252,6 +266,7 @@ the output rules to more than one argument (as shown previously).
<p> <p>
If the function also returns a value, it is returned along with the argument. For example, If the function also returns a value, it is returned along with the argument. For example,
if you had this: if you had this:
</p>
<blockquote><pre> <blockquote><pre>
extern int foo(double a, double b, double *OUTPUT); extern int foo(double a, double b, double *OUTPUT);
@ -265,11 +280,12 @@ iresult, dresult = foo(3.5, 2)
</pre> </pre>
</blockquote> </blockquote>
<a name="n6"></a><H3>7.1.4 Input/Output parameters</H3> <H3><a name="Arguments_nn6"></a>9.1.4 Input/Output parameters</H3>
<p>
When a pointer serves as both an input and output value you can use When a pointer serves as both an input and output value you can use
the following typemaps :<p> the following typemaps :</p>
<blockquote><pre> <blockquote><pre>
int *INOUT int *INOUT
@ -283,30 +299,33 @@ float *INOUT
</pre></blockquote> </pre></blockquote>
A C function that uses this might be something like this:<p>
<p> <p>
<blockquote><pre>void negate(double *x) { A C function that uses this might be something like this:</p>
<blockquote><pre>
void negate(double *x) {
*x = -(*x); *x = -(*x);
} }
</pre></blockquote> </pre></blockquote>
To make x function as both and input and output value, declare the
function like this in an interface file :<p>
<p> <p>
<blockquote><pre>%module example To make x function as both and input and output value, declare the
function like this in an interface file :</p>
<blockquote><pre>
%module example
%include typemaps.i %include typemaps.i
... ...
extern void negate(double *INOUT); extern void negate(double *INOUT);
</pre></blockquote> </pre></blockquote>
Now within a script, you can simply call the function normally :<p>
<p> <p>
<blockquote><pre>a = negate(3); # a = -3 after calling this Now within a script, you can simply call the function normally :</p>
<blockquote><pre>
a = negate(3); # a = -3 after calling this
</pre></blockquote> </pre></blockquote>
One subtle point of the <tt>INOUT</tt> rule is that many scripting languages One subtle point of the <tt>INOUT</tt> rule is that many scripting languages
@ -319,15 +338,18 @@ rather than directly overwriting the value of the original input object.
<p> <p>
<b>Compatibility note :</b> The <tt>INOUT</tt> rule used to be known as <tt>BOTH</tt> in earlier versions of <b>Compatibility note :</b> The <tt>INOUT</tt> rule used to be known as <tt>BOTH</tt> in earlier versions of
SWIG. Backwards compatibility is preserved, but deprecated. SWIG. Backwards compatibility is preserved, but deprecated.
</p>
<a name="n7"></a><H3>7.1.5 Using different names</H3> <H3><a name="Arguments_nn7"></a>9.1.5 Using different names</H3>
As previously shown, the <tt>%apply</tt> directive can be used to apply the <tt>INPUT</tt>, <tt>OUTPUT</tt>, and
<tt>INOUT</tt> typemaps to different argument names. For example:
<p> <p>
<blockquote><pre>// Make double *result an output value As previously shown, the <tt>%apply</tt> directive can be used to apply the <tt>INPUT</tt>, <tt>OUTPUT</tt>, and
<tt>INOUT</tt> typemaps to different argument names. For example:
</p>
<blockquote><pre>
// Make double *result an output value
%apply double *OUTPUT { double *result }; %apply double *OUTPUT { double *result };
// Make Int32 *in an input value // Make Int32 *in an input value
@ -340,15 +362,15 @@ As previously shown, the <tt>%apply</tt> directive can be used to apply the <tt>
To clear a rule, the <tt>%clear</tt> directive is used: To clear a rule, the <tt>%clear</tt> directive is used:
<p> <blockquote><pre>
<blockquote><pre>%clear double *result; %clear double *result;
%clear Int32 *in, long *x; %clear Int32 *in, long *x;
</pre></blockquote> </pre></blockquote>
Typemap declarations are lexically scoped so a typemap takes effect from the point of definition to the end of the Typemap declarations are lexically scoped so a typemap takes effect from the point of definition to the end of the
file or a matching <tt>%clear</tt> declaration. file or a matching <tt>%clear</tt> declaration.
<a name="n8"></a><H2>7.2 Applying constraints to input values</H2> <H2><a name="Arguments_nn8"></a>9.2 Applying constraints to input values</H2>
In addition to changing the handling of various input values, it is In addition to changing the handling of various input values, it is
@ -356,14 +378,15 @@ also possible to use typemaps to apply constraints. For example, maybe you want
insure that a value is positive, or that a pointer is non-NULL. This insure that a value is positive, or that a pointer is non-NULL. This
can be accomplished including the <tt>constraints.i</tt> library file. can be accomplished including the <tt>constraints.i</tt> library file.
<a name="n9"></a><H3>7.2.1 Simple constraint example</H3> <H3><a name="Arguments_nn9"></a>9.2.1 Simple constraint example</H3>
The constraints library is best illustrated by the following interface
file :<p>
<p> <p>
The constraints library is best illustrated by the following interface
file :</p>
<blockquote><pre>// Interface file with constraints <blockquote><pre>
// Interface file with constraints
%module example %module example
%include "constraints.i" %include "constraints.i"
@ -375,15 +398,17 @@ void free(void *NONNULL); // Non-NULL pointers only
</pre></blockquote> </pre></blockquote>
<p>
The behavior of this file is exactly as you would expect. If any of The behavior of this file is exactly as you would expect. If any of
the arguments violate the constraint condition, a scripting language the arguments violate the constraint condition, a scripting language
exception will be raised. As a result, it is possible to catch bad exception will be raised. As a result, it is possible to catch bad
values, prevent mysterious program crashes and so on.<p> values, prevent mysterious program crashes and so on.</p>
<a name="n10"></a><H3>7.2.2 Constraint methods</H3> <H3><a name="Arguments_nn10"></a>9.2.2 Constraint methods</H3>
The following constraints are currently available<p> <p>
The following constraints are currently available</p>
<blockquote><pre> <blockquote><pre>
POSITIVE Any number &gt; 0 (not zero) POSITIVE Any number &gt; 0 (not zero)
@ -395,15 +420,16 @@ NONNULL Non-NULL pointer (pointers only).
</pre></blockquote> </pre></blockquote>
<a name="n11"></a><H3>7.2.3 Applying constraints to new datatypes</H3> <H3><a name="Arguments_nn11"></a>9.2.3 Applying constraints to new datatypes</H3>
<p>
The constraints library only supports the primitive C datatypes, but it The constraints library only supports the primitive C datatypes, but it
is easy to apply it to new datatypes using <tt>%apply</tt>. For is easy to apply it to new datatypes using <tt>%apply</tt>. For
example :<p> example :</p>
<p>
<blockquote><pre>// Apply a constraint to a Real variable <blockquote><pre>
// Apply a constraint to a Real variable
%apply Number POSITIVE { Real in }; %apply Number POSITIVE { Real in };
// Apply a constraint to a pointer type // Apply a constraint to a pointer type
@ -411,17 +437,17 @@ example :<p>
</pre></blockquote> </pre></blockquote>
<p>
The special types of "Number" and "Pointer" can be applied to any The special types of "Number" and "Pointer" can be applied to any
numeric and pointer variable type respectively. To later remove a numeric and pointer variable type respectively. To later remove a
constraint, the <tt>%clear</tt> directive can be used :<p> constraint, the <tt>%clear</tt> directive can be used :</p>
<p> <blockquote><pre>
<blockquote><pre>%clear Real in; %clear Real in;
%clear Vector *; %clear Vector *;
</pre></blockquote> </pre></blockquote>
<p><hr> <hr>
<address>SWIG 1.3 - Last Modified : October 13, 2002</address> <address>SWIG 1.3 - Last Modified : October 13, 2002</address>
</body> </body>
</html> </html>

View file

@ -4,12 +4,12 @@
<title>SWIG and C#</title> <title>SWIG and C#</title>
</head> </head>
<body bgcolor="#FFFFFF"> <body bgcolor="#FFFFFF">
<a name="n1"></a><H1>15 SWIG and C#</H1> <H1><a name="CSharp"></a>16 SWIG and C#</H1>
<!-- INDEX --> <!-- INDEX -->
<ul>
</ul>
<!-- INDEX --> <!-- INDEX -->
The purpose of the C# module is to offer an automated way of accessing existing C/C++ code from .NET languages. The purpose of the C# module is to offer an automated way of accessing existing C/C++ code from .NET languages.
The wrapper code implementation uses the Platform Invoke (PINVOKE) interface to access natively compiled C/C++ code. The wrapper code implementation uses the Platform Invoke (PINVOKE) interface to access natively compiled C/C++ code.
The PINVOKE interface has been chosen over Microsoft's Managed C++ interface as it is portable to both Microsoft Windows and non-Microsoft platforms. The PINVOKE interface has been chosen over Microsoft's Managed C++ interface as it is portable to both Microsoft Windows and non-Microsoft platforms.
@ -18,7 +18,7 @@ PINVOKE is part of the ECMA/ISO C# specification.
<p> <p>
The C# module is one of the more recently added language modules to SWIG and consequently is missing some functionality available in some other SWIG modules. The C# module is one of the more recently added language modules to SWIG and consequently is missing some functionality available in some other SWIG modules.
The C# module is very similar to the Java module, so until some documentation has been written, The C# module is very similar to the Java module, so until some documentation has been written,
please use the <a href="Java.html">Java documentation</a> as a guide to using SWIG with C#. please use the <a href="Java.html#Java">Java documentation</a> as a guide to using SWIG with C#.
The rest of this chapter should be read in conjunction with the Java documentation as it lists the main differences. The rest of this chapter should be read in conjunction with the Java documentation as it lists the main differences.
<p> <p>
@ -52,7 +52,7 @@ There is no implementation for type unsafe enums - not deemed necessary.
<li> <li>
The default enum wrapping approach is proper C# enums, not typesafe enums. The default enum wrapping approach is proper C# enums, not typesafe enums.
<br/> <br>
Note that %csconst(0) will be ignored when wrapping C/C++ enums with proper C# enums. Note that %csconst(0) will be ignored when wrapping C/C++ enums with proper C# enums.
This is because C# enum items must be initialised from a compile time constant. This is because C# enum items must be initialised from a compile time constant.
If an enum item has an initialiser and the initialiser doesn't compile as C# code, If an enum item has an initialiser and the initialiser doesn't compile as C# code,
@ -70,20 +70,20 @@ Likewise there is no need for an equivalent to <tt>%javaexception</tt>.
Typemap equivalent names: Typemap equivalent names:
<blockquote><pre> <blockquote><pre>
jni -> ctype jni -&gt; ctype
jtype -> imtype jtype -&gt; imtype
jstype -> cstype jstype -&gt; cstype
javain -> csin javain -&gt; csin
javaout -> csout javaout -&gt; csout
javainterfaces -> csinterfaces and csinterfaces_derived javainterfaces -&gt; csinterfaces and csinterfaces_derived
javabase -> csbase javabase -&gt; csbase
javaclassmodifiers -> csclassmodifiers javaclassmodifiers -&gt; csclassmodifiers
javacode -> cscode javacode -&gt; cscode
javaimports -> csimports javaimports -&gt; csimports
javabody -> csbody javabody -&gt; csbody
javafinalize -> csfinalize javafinalize -&gt; csfinalize
javadestruct -> csdestruct javadestruct -&gt; csdestruct
javadestruct_derived -> csdestruct_derived javadestruct_derived -&gt; csdestruct_derived
</pre></blockquote> </pre></blockquote>
</li> </li>
@ -101,30 +101,30 @@ csvarout C# code property get typemap
<li> <li>
Feature equivalent names: Feature equivalent names:
<blockquote><pre> <blockquote><pre>
%javaconst -> %csconst %javaconst -&gt; %csconst
%javaconstvalue -> %csconstvalue %javaconstvalue -&gt; %csconstvalue
%javamethodmodifiers -> %csmethodmodifiers %javamethodmodifiers -&gt; %csmethodmodifiers
</pre></blockquote> </pre></blockquote>
</li> </li>
<li> <li>
Pragma equivalent names: Pragma equivalent names:
<blockquote><pre> <blockquote><pre>
%pragma(java) -> %pragma(csharp) %pragma(java) -&gt; %pragma(csharp)
jniclassbase -> imclassbase jniclassbase -&gt; imclassbase
jniclassclassmodifiers -> imclassclassmodifiers jniclassclassmodifiers -&gt; imclassclassmodifiers
jniclasscode -> imclasscode jniclasscode -&gt; imclasscode
jniclassimports -> imclassimports jniclassimports -&gt; imclassimports
jniclassinterfaces -> imclassinterfaces jniclassinterfaces -&gt; imclassinterfaces
</pre></blockquote> </pre></blockquote>
</li> </li>
<li> <li>
Special variable equivalent names: Special variable equivalent names:
<blockquote><pre> <blockquote><pre>
$javaclassname -> $csclassname $javaclassname -&gt; $csclassname
$javainput -> $csinput $javainput -&gt; $csinput
$jnicall -> $imcall $jnicall -&gt; $imcall
</pre></blockquote> </pre></blockquote>
</li> </li>

View file

@ -7,31 +7,31 @@
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>25 SWIG and Chicken</H1> <H1><a name="Chicken"></a>17 SWIG and Chicken</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">Preliminaries</a> <li><a href="#Chicken_nn2">Preliminaries</a>
<ul> <ul>
<li><a href="#n3">Running SWIG in C mode</a> <li><a href="#Chicken_nn3">Running SWIG in C mode</a>
<li><a href="#n4">Running SWIG in C++ mode</a> <li><a href="#Chicken_nn4">Running SWIG in C++ mode</a>
</ul> </ul>
<li><a href="#n5">Code Generation</a> <li><a href="#Chicken_nn5">Code Generation</a>
<ul> <ul>
<li><a href="#n6">Naming Conventions</a> <li><a href="#Chicken_nn6">Naming Conventions</a>
<li><a href="#n7">Modules and Prefixes</a> <li><a href="#Chicken_nn7">Modules and Prefixes</a>
<li><a href="#n8">Constants and Variables</a> <li><a href="#Chicken_nn8">Constants and Variables</a>
<li><a href="#n9">Functions</a> <li><a href="#Chicken_nn9">Functions</a>
</ul> </ul>
<li><a href="#n10">TinyCLOS</a> <li><a href="#Chicken_nn10">TinyCLOS</a>
<li><a href="#n11">Compilation</a> <li><a href="#Chicken_nn11">Compilation</a>
<li><a href="#n12">Linkage</a> <li><a href="#Chicken_nn12">Linkage</a>
<ul> <ul>
<li><a href="#n13">Shared library</a> <li><a href="#Chicken_nn13">Shared library</a>
<li><a href="#n14">Static binary</a> <li><a href="#Chicken_nn14">Static binary</a>
</ul> </ul>
<li><a href="#n15">Typemaps</a> <li><a href="#Chicken_nn15">Typemaps</a>
<li><a href="#n16">Pointers</a> <li><a href="#Chicken_nn16">Pointers</a>
<li><a href="#n17">Unsupported features</a> <li><a href="#Chicken_nn17">Unsupported features</a>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -61,7 +61,7 @@
</p> </p>
<a name="n2"></a><H2>25.1 Preliminaries</H2> <H2><a name="Chicken_nn2"></a>17.1 Preliminaries</H2>
<p> <p>
@ -82,61 +82,77 @@
</p> </p>
<a name="n3"></a><H3>25.1.1 Running SWIG in C mode</H3> <H3><a name="Chicken_nn3"></a>17.1.1 Running SWIG in C mode</H3>
<p> <p>
To run SWIG CHICKEN in C mode, use To run SWIG CHICKEN in C mode, use
the -chicken option. the -chicken option.
</p>
<blockquote> <blockquote>
<pre>% swig -chicken example.i</pre> <pre>% swig -chicken example.i</pre>
</blockquote> </blockquote>
<p>
To allow the wrapper to take advantage of future CHICKEN code To allow the wrapper to take advantage of future CHICKEN code
generation improvements, part of the wrapper is direct CHICKEN generation improvements, part of the wrapper is direct CHICKEN
function calls (<tt>example_wrap.c</tt>) and part is CHICKEN function calls (<tt>example_wrap.c</tt>) and part is CHICKEN
Scheme (<tt>example.scm</tt>). The basic Scheme code must Scheme (<tt>example.scm</tt>). The basic Scheme code must
be compiled to C using your system's CHICKEN compiler. be compiled to C using your system's CHICKEN compiler.
</p>
<blockquote> <blockquote>
<pre>% chicken example.scm -output-file oexample.c</pre> <pre>% chicken example.scm -output-file oexample.c</pre>
</blockquote> </blockquote>
<p>
So for the C mode of SWIG CHICKEN, <tt>example_wrap.c</tt> and So for the C mode of SWIG CHICKEN, <tt>example_wrap.c</tt> and
<tt>oexample.c</tt> are the files that must be compiled to <tt>oexample.c</tt> are the files that must be compiled to
object files and linked into your project. object files and linked into your project.
</p> </p>
<a name="n4"></a><H3>25.1.2 Running SWIG in C++ mode</H3> <H3><a name="Chicken_nn4"></a>17.1.2 Running SWIG in C++ mode</H3>
<p> <p>
To run SWIG CHICKEN in C++ mode, use To run SWIG CHICKEN in C++ mode, use
the -chicken -c++ option. the -chicken -c++ option.
</p>
<blockquote> <blockquote>
<pre>% swig -chicken -c++ example.i</pre> <pre>% swig -chicken -c++ example.i</pre>
</blockquote> </blockquote>
<p>
This will generate <tt>example_wrap.cxx</tt>, This will generate <tt>example_wrap.cxx</tt>,
<tt>example.scm</tt>, <tt>example-generic.scm</tt> and <tt>example.scm</tt>, <tt>example-generic.scm</tt> and
<tt>example-clos.scm</tt>. The basic Scheme code must be <tt>example-clos.scm</tt>. The basic Scheme code must be
compiled to C using your system's CHICKEN compiler. compiled to C using your system's CHICKEN compiler.
</p>
<blockquote> <blockquote>
<pre>% chicken example.scm -output-file oexample.c</pre> <pre>% chicken example.scm -output-file oexample.c</pre>
</blockquote> </blockquote>
<p>
So for the C++ mode of SWIG CHICKEN, <tt>example_wrap.cxx</tt> So for the C++ mode of SWIG CHICKEN, <tt>example_wrap.cxx</tt>
and <tt>oexample.c</tt> are the files that must be compiled to and <tt>oexample.c</tt> are the files that must be compiled to
object files and linked into your project. object files and linked into your project.
</p> </p>
<a name="n5"></a><H2>25.2 Code Generation</H2> <H2><a name="Chicken_nn5"></a>17.2 Code Generation</H2>
<a name="n6"></a><H3>25.2.1 Naming Conventions</H3> <H3><a name="Chicken_nn6"></a>17.2.1 Naming Conventions</H3>
<p> <p>
Given a C variable, function or constant declaration named Given a C variable, function or constant declaration named
<tt>Foo_Bar_to_Foo_Baz</tt>, the declaration will be available <tt>Foo_Bar_to_Foo_Baz</tt>, the declaration will be available
in CHICKEN as an identifier ending with in CHICKEN as an identifier ending with
<tt>Foo-Bar->Foo-Baz</tt>. That is, an underscore is converted <tt>Foo-Bar-&gt;Foo-Baz</tt>. That is, an underscore is converted
to a dash and '_to_' is converted to an arrow. to a dash and '_to_' is converted to an arrow.
<br> <br>
@ -156,7 +172,7 @@
<tt>%rename</tt> SWIG directive in the SWIG interface file. <tt>%rename</tt> SWIG directive in the SWIG interface file.
</p> </p>
<a name="n7"></a><H3>25.2.2 Modules and Prefixes</H3> <H3><a name="Chicken_nn7"></a>17.2.2 Modules and Prefixes</H3>
<p> <p>
@ -192,7 +208,7 @@
</p> </p>
<a name="n8"></a><H3>25.2.3 Constants and Variables</H3> <H3><a name="Chicken_nn8"></a>17.2.3 Constants and Variables</H3>
<p> <p>
@ -219,7 +235,7 @@
use <tt>(my-variable)</tt>. use <tt>(my-variable)</tt>.
</p> </p>
<a name="n9"></a><H3>25.2.4 Functions</H3> <H3><a name="Chicken_nn9"></a>17.2.4 Functions</H3>
<p> <p>
@ -238,11 +254,12 @@
parameters). parameters).
</p> </p>
<a name="n10"></a><H2>25.3 TinyCLOS</H2> <H2><a name="Chicken_nn10"></a>17.3 TinyCLOS</H2>
<p> <p>
The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as: The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as:
</p>
<blockquote> <blockquote>
Tiny CLOS is a Scheme implementation of a `kernelized' CLOS, with a Tiny CLOS is a Scheme implementation of a `kernelized' CLOS, with a
metaobject protocol. The implementation is even simpler than metaobject protocol. The implementation is even simpler than
@ -250,12 +267,15 @@
weighing in at around 850 lines of code, including (some) weighing in at around 850 lines of code, including (some)
comments and documentation. comments and documentation.
</blockquote> </blockquote>
<p>
Almost all good Scheme books describe how to use metaobjects and Almost all good Scheme books describe how to use metaobjects and
generic procedures to implement an object-oriented Scheme generic procedures to implement an object-oriented Scheme
system. Please consult a Scheme book if you are unfamiliar system. Please consult a Scheme book if you are unfamiliar
with the concept. with the concept.
</p>
<br> <p>
CHICKEN has a modified version of TinyCLOS, which SWIG CHICKEN CHICKEN has a modified version of TinyCLOS, which SWIG CHICKEN
uses in C++ mode. SWIG CHICKEN generates a uses in C++ mode. SWIG CHICKEN generates a
@ -265,8 +285,9 @@
program needs, and <strong>then</strong> <tt>(include program needs, and <strong>then</strong> <tt>(include
"xxx-clos")</tt> all the metaobject (class) macros your program "xxx-clos")</tt> all the metaobject (class) macros your program
needs. needs.
</p>
<br> <p>
SWIG CHICKEN will call the destructor for all TinyCLOS objects SWIG CHICKEN will call the destructor for all TinyCLOS objects
that are garbage-collected by CHICKEN. It also allows access to that are garbage-collected by CHICKEN. It also allows access to
@ -274,9 +295,9 @@
of any TinyCLOS parameters. It is best to learn the TinyCLOS of any TinyCLOS parameters. It is best to learn the TinyCLOS
system by running the <tt>Examples/chicken/class/</tt> example. system by running the <tt>Examples/chicken/class/</tt> example.
</p> </p>
<a name="n11"></a><H2>25.4 Compilation</H2> <H2><a name="Chicken_nn11"></a>17.4 Compilation</H2>
<p> <p>
@ -290,7 +311,7 @@
much simpler <tt>csc</tt> or <tt>csc.bat</tt>. much simpler <tt>csc</tt> or <tt>csc.bat</tt>.
</p> </p>
<a name="n12"></a><H2>25.5 Linkage</H2> <H2><a name="Chicken_nn12"></a>17.5 Linkage</H2>
<p> <p>
@ -304,7 +325,7 @@
loadable module. loadable module.
</p> </p>
<a name="n13"></a><H3>25.5.1 Shared library</H3> <H3><a name="Chicken_nn13"></a>17.5.1 Shared library</H3>
<p> <p>
@ -313,42 +334,47 @@
in example.i and the C functions being wrapped are in example_impl.c. in example.i and the C functions being wrapped are in example_impl.c.
</p> </p>
<pre><blockquote> <blockquote>
<pre>
$ swig -chicken example.i $ swig -chicken example.i
$ csc -svk example.scm example_impl.c example_wrap.c $ csc -svk example.scm example_impl.c example_wrap.c
$ csi example.so test_script.scm $ csi example.so test_script.scm
</blockquote></pre> </pre>
</blockquote>
<p> <p>
You must be careful not to name the example_impl.c file example.c because You must be careful not to name the example_impl.c file example.c because
when compiling example.scm, csc compiles that into example.c! when compiling example.scm, csc compiles that into example.c!
</p> </p>
<a name="n14"></a><H3>25.5.2 Static binary</H3> <H3><a name="Chicken_nn14"></a>17.5.2 Static binary</H3>
<p>Again, we can easily use csc to build a binary.</p> <p>Again, we can easily use csc to build a binary.</p>
<pre><blockquote> <blockquote>
<pre>
$ swig -chicken example.i $ swig -chicken example.i
$ csc -vk example.scm example_impl.c example_wrap.c test_script.scm -o example $ csc -vk example.scm example_impl.c example_wrap.c test_script.scm -o example
$ ./example $ ./example
</blockquote></pre> </pre>
</blockquote>
<a name="n15"></a><H2>25.6 Typemaps</H2> <H2><a name="Chicken_nn15"></a>17.6 Typemaps</H2>
<p> <p>
The Chicken module handles all types via typemaps. This information is The Chicken module handles all types via typemaps. This information is
read from <code>Lib/chicken/typemaps.i</code> and read from <code>Lib/chicken/typemaps.i</code> and
<code>Lib/chicken/chicken.swg</code>. <code>Lib/chicken/chicken.swg</code>.
</p>
<br> <p>
Two Chicken-specific typemaps are supported: Two Chicken-specific typemaps are supported:
<code>clos_in</code> and <code>clos_out</code>. They are for <code>clos_in</code> and <code>clos_out</code>. They are for
converting TinyCLOS to and from low-level CHICKEN SWIG. Here is converting TinyCLOS to and from low-level CHICKEN SWIG. Here is
a quick example: a quick example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -365,7 +391,7 @@
<blockquote> <blockquote>
<pre> <pre>
/* TinyCLOS <--> Low-level CHICKEN */ /* TinyCLOS &lt;--&gt; Low-level CHICKEN */
%typemap("clos_in") SIMPLE_CLOS_OBJECT * "(slot-ref $input (quote this))" %typemap("clos_in") SIMPLE_CLOS_OBJECT * "(slot-ref $input (quote this))"
%typemap("clos_out") SIMPLE_CLOS_OBJECT * "(make $class (quote this) $1)" %typemap("clos_out") SIMPLE_CLOS_OBJECT * "(make $class (quote this) $1)"
@ -457,6 +483,7 @@
</pre> </pre>
</blockquote> </blockquote>
<p>
After SWIG processes <code>vtkObject.h</code> (from the After SWIG processes <code>vtkObject.h</code> (from the
<tt>%include "vtkObject.h"</tt> line), SWIG will have the complete <tt>%include "vtkObject.h"</tt> line), SWIG will have the complete
definition of the <code>vtkObject</code> class because definition of the <code>vtkObject</code> class because
@ -475,7 +502,7 @@
</p> </p>
<a name="n16"></a><H2>25.7 Pointers</H2> <H2><a name="Chicken_nn16"></a>17.7 Pointers</H2>
<p> <p>
@ -508,7 +535,7 @@
type. type.
</p> </p>
<a name="n17"></a><H2>25.8 Unsupported features</H2> <H2><a name="Chicken_nn17"></a>17.8 Unsupported features</H2>
<ul> <ul>

File diff suppressed because it is too large Load diff

View file

@ -5,13 +5,13 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>10 Contracts</H1> <H1><a name="Contract"></a>12 Contracts</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">The %contract directive</a> <li><a href="#Contract_nn2">The %contract directive</a>
<li><a href="#n3">%contract and classes</a> <li><a href="#Contract_nn3">%contract and classes</a>
<li><a href="#n4">Constant aggregation and %aggregate_check</a> <li><a href="#Contract_nn4">Constant aggregation and %aggregate_check</a>
<li><a href="#n5">Notes</a> <li><a href="#Contract_nn5">Notes</a>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -31,8 +31,9 @@ to a declaration. For example, you can easily attach argument checking rules,
check the output values of a function and more. check the output values of a function and more.
When one of the rules is violated by a script, a runtime exception is When one of the rules is violated by a script, a runtime exception is
generated rather than having the program continue to execute. generated rather than having the program continue to execute.
</p>
<a name="n2"></a><H2>10.1 The %contract directive</H2> <H2><a name="Contract_nn2"></a>12.1 The %contract directive</H2>
Contracts are added to a declaration using the %contract directive. Here Contracts are added to a declaration using the %contract directive. Here
@ -42,9 +43,9 @@ is a simple example:
<pre> <pre>
%contract sqrt(double x) { %contract sqrt(double x) {
require: require:
x >= 0; x &gt;= 0;
ensure: ensure:
sqrt >= 0; sqrt &gt;= 0;
} }
... ...
@ -65,24 +66,26 @@ cases, the conditions that must hold must be specified as boolean expressions.
<p> <p>
In the above example, we're simply making sure that sqrt() returns a non-negative In the above example, we're simply making sure that sqrt() returns a non-negative
number (if it didn't, then it would be broken in some way). number (if it didn't, then it would be broken in some way).
</p>
<p> <p>
Once a contract has been specified, it modifies the behavior of the Once a contract has been specified, it modifies the behavior of the
resulting module. For example: resulting module. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
>>> example.sqrt(2) &gt;&gt;&gt; example.sqrt(2)
1.4142135623730951 1.4142135623730951
>>> example.sqrt(-2) &gt;&gt;&gt; example.sqrt(-2)
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in ? File "&lt;stdin&gt;", line 1, in ?
RuntimeError: Contract violation: require: (arg1>=0) RuntimeError: Contract violation: require: (arg1&gt;=0)
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
<a name="n3"></a><H2>10.2 %contract and classes</H2> <H2><a name="Contract_nn3"></a>12.2 %contract and classes</H2>
The <tt>%contract</tt> directive can also be applied to class methods and constructors. For example: The <tt>%contract</tt> directive can also be applied to class methods and constructors. For example:
@ -91,14 +94,14 @@ The <tt>%contract</tt> directive can also be applied to class methods and constr
<pre> <pre>
%contract Foo::bar(int x, int y) { %contract Foo::bar(int x, int y) {
require: require:
x > 0; x &gt; 0;
ensure: ensure:
bar > 0; bar &gt; 0;
} }
%contract Foo::Foo(int a) { %contract Foo::Foo(int a) {
require: require:
a > 0; a &gt; 0;
} }
class Foo { class Foo {
@ -127,12 +130,12 @@ In addition to this, separate contracts can be applied to both the base class an
<pre> <pre>
%contract Foo::bar(int x, int) { %contract Foo::bar(int x, int) {
require: require:
x > 0; x &gt; 0;
} }
%contract Spam::bar(int, int y) { %contract Spam::bar(int, int y) {
require: require:
y > 0; y &gt; 0;
} }
class Foo { class Foo {
@ -153,7 +156,7 @@ In other words conditions specified for the base class and conditions
specified for the derived class all must hold. In the above example, specified for the derived class all must hold. In the above example,
this means that both the arguments to <tt>Spam::bar</tt> must be positive. this means that both the arguments to <tt>Spam::bar</tt> must be positive.
<a name="n4"></a><H2>10.3 Constant aggregation and %aggregate_check</H2> <H2><a name="Contract_nn4"></a>12.3 Constant aggregation and %aggregate_check</H2>
Consider an interface file that contains the following code: Consider an interface file that contains the following code:
@ -229,13 +232,13 @@ void move(SomeObject *, int direction, int distance);
Regrettably, there is no automatic way to perform similar checks with enums values. Maybe in a future Regrettably, there is no automatic way to perform similar checks with enums values. Maybe in a future
release. release.
<a name="n5"></a><H2>10.4 Notes</H2> <H2><a name="Contract_nn5"></a>12.4 Notes</H2>
Contract support was implemented by Songyan (Tiger) Feng and first appeared Contract support was implemented by Songyan (Tiger) Feng and first appeared
in SWIG-1.3.20. in SWIG-1.3.20.
<p><hr> <hr>
<address>SWIG 1.3 - Last Modified : November 12, 2003</address> <address>SWIG 1.3 - Last Modified : November 12, 2003</address>
</body> </body>

View file

@ -5,19 +5,19 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>9 Customization Features</H1> <H1><a name="Customization"></a>11 Customization Features</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">Exception handling with %exception</a> <li><a href="#exception">Exception handling with %exception</a>
<ul> <ul>
<li><a href="#n3">Handling exceptions in C code</a> <li><a href="#Customization_nn3">Handling exceptions in C code</a>
<li><a href="#n4">Exception handling with longjmp()</a> <li><a href="#Customization_nn4">Exception handling with longjmp()</a>
<li><a href="#n5">Handling C++ exceptions</a> <li><a href="#Customization_nn5">Handling C++ exceptions</a>
<li><a href="#n6">Defining different exception handlers</a> <li><a href="#Customization_nn6">Defining different exception handlers</a>
<li><a href="#n7">Using The SWIG exception library</a> <li><a href="#Customization_nn7">Using The SWIG exception library</a>
</ul> </ul>
<li><a href="#n8">Object ownership and %newobject</a> <li><a href="#ownership">Object ownership and %newobject</a>
<li><a href="#n9">Features and the %feature directive</a> <li><a href="#features">Features and the %feature directive</a>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -31,15 +31,16 @@ describes some of these customization techniques. First, a discussion
of exception handling is presented. Then, a more general-purpose of exception handling is presented. Then, a more general-purpose
customization mechanism known as "features" is described. customization mechanism known as "features" is described.
<a name="exception"> <H2><a name="exception"></a>11.1 Exception handling with %exception</H2>
<a name="n2"></a><H2>9.1 Exception handling with %exception</H2>
The <tt>%exception</tt> directive allows you to define a general purpose exception
handler. For example, you can specify the following:
<p> <p>
<blockquote><pre>%exception { The <tt>%exception</tt> directive allows you to define a general purpose exception
handler. For example, you can specify the following:
</p>
<blockquote><pre>
%exception {
try { try {
$action $action
} }
@ -49,31 +50,34 @@ handler. For example, you can specify the following:
} }
} }
</pre></blockquote> </pre></blockquote>
<p>
<p>
When defined, the code enclosed in braces is inserted directly into the low-level wrapper When defined, the code enclosed in braces is inserted directly into the low-level wrapper
functions. The special symbol <tt>$action</tt> gets replaced with the actual operation functions. The special symbol <tt>$action</tt> gets replaced with the actual operation
to be performed (a function call, method invocation, attribute access, etc.). An exception handler to be performed (a function call, method invocation, attribute access, etc.). An exception handler
remains in effect until it is explicitly deleted. This is done by using either <tt>%exception</tt> remains in effect until it is explicitly deleted. This is done by using either <tt>%exception</tt>
or <tt>%noexception</tt> with no code. For example: or <tt>%noexception</tt> with no code. For example:
<p> </p>
<blockquote><pre>%exception; // Deletes any previously defined handler
<blockquote><pre>
%exception; // Deletes any previously defined handler
</pre></blockquote> </pre></blockquote>
<p> <p>
<b>Compatibility note:</b> Previous versions of SWIG used a special directive <tt>%except</tt> <b>Compatibility note:</b> Previous versions of SWIG used a special directive <tt>%except</tt>
for exception handling. That directive is still supported but is deprecated--<tt>%exception</tt> for exception handling. That directive is still supported but is deprecated--<tt>%exception</tt>
provides the same functionality, but is substantially more flexible. provides the same functionality, but is substantially more flexible.
</p>
<a name="n3"></a><H3>9.1.1 Handling exceptions in C code</H3> <H3><a name="Customization_nn3"></a>11.1.1 Handling exceptions in C code</H3>
C has no formal exception handling mechanism so there are several approaches that might be
used. A somewhat common technique is to simply set a special error code. For example:
<p> <p>
<blockquote><pre> C has no formal exception handling mechanism so there are several approaches that might be
used. A somewhat common technique is to simply set a special error code. For example:
</p>
<blockquote><pre>
/* File : except.c */ /* File : except.c */
static char error_message[256]; static char error_message[256];
@ -94,11 +98,13 @@ char *check_exception() {
</pre></blockquote> </pre></blockquote>
<p>
To use these functions, functions simply call To use these functions, functions simply call
<tt>throw_exception()</tt> to indicate an error occurred. For example <tt>throw_exception()</tt> to indicate an error occurred. For example
:<p> :</p>
<p>
<blockquote><pre>double inv(double x) { <blockquote><pre>
double inv(double x) {
if (x != 0) return 1.0/x; if (x != 0) return 1.0/x;
else { else {
throw_exception("Division by zero"); throw_exception("Division by zero");
@ -108,11 +114,12 @@ To use these functions, functions simply call
</pre></blockquote> </pre></blockquote>
To catch the exception, you can write a simple exception handler such
as the following (shown for Perl5) :<p>
<p> <p>
<blockquote><pre>%exception { To catch the exception, you can write a simple exception handler such
as the following (shown for Perl5) :</p>
<blockquote><pre>
%exception {
char *err; char *err;
clear_exception(); clear_exception();
$action $action
@ -121,10 +128,12 @@ as the following (shown for Perl5) :<p>
} }
} }
</pre></blockquote> </pre></blockquote>
<p> <p>
In this case, when an error occurs, it is translated into a Perl error. In this case, when an error occurs, it is translated into a Perl error.
</p>
<a name="n4"></a><H3>9.1.2 Exception handling with longjmp()</H3> <H3><a name="Customization_nn4"></a>11.1.2 Exception handling with longjmp()</H3>
Exception handling can also be added to C code using the Exception handling can also be added to C code using the
@ -157,20 +166,22 @@ extern int exception_status;
</pre></blockquote> </pre></blockquote>
Now, within a C program, you can do the following :<p>
<p> <p>
<blockquote><pre>double inv(double x) { Now, within a C program, you can do the following :</p>
<blockquote><pre>
double inv(double x) {
if (x) return 1.0/x; if (x) return 1.0/x;
else throw(DivisionByZero); else throw(DivisionByZero);
} }
</pre></blockquote> </pre></blockquote>
Finally, to create a SWIG exception handler, write the following :<p>
<p> <p>
<blockquote><pre>%{ Finally, to create a SWIG exception handler, write the following :</p>
<blockquote><pre>
%{
#include "except.h" #include "except.h"
%} %}
@ -192,13 +203,15 @@ Finally, to create a SWIG exception handler, write the following :<p>
Note: This implementation is only intended to illustrate the general idea. To make it work better, you'll need to Note: This implementation is only intended to illustrate the general idea. To make it work better, you'll need to
modify it to handle nested <tt>try</tt> declarations. modify it to handle nested <tt>try</tt> declarations.
<a name="n5"></a><H3>9.1.3 Handling C++ exceptions</H3> <H3><a name="Customization_nn5"></a>11.1.3 Handling C++ exceptions</H3>
Handling C++ exceptions is also straightforward. For example:
<p> <p>
<blockquote><pre>%exception { Handling C++ exceptions is also straightforward. For example:
</p>
<blockquote><pre>
%exception {
try { try {
$action $action
} catch(RangeError) { } catch(RangeError) {
@ -214,17 +227,18 @@ Handling C++ exceptions is also straightforward. For example:
</pre></blockquote> </pre></blockquote>
The exception types need to be declared as classes elsewhere, possibly
in a header file :<p>
<p> <p>
<blockquote><pre>class RangeError {}; The exception types need to be declared as classes elsewhere, possibly
in a header file :</p>
<blockquote><pre>
class RangeError {};
class DivisionByZero {}; class DivisionByZero {};
class OutOfMemory {}; class OutOfMemory {};
</pre> </pre>
</blockquote> </blockquote>
<a name="n6"></a><H3>9.1.4 Defining different exception handlers</H3> <H3><a name="Customization_nn6"></a>11.1.4 Defining different exception handlers</H3>
By default, the <tt>%exception</tt> directive creates an exception By default, the <tt>%exception</tt> directive creates an exception
@ -232,14 +246,15 @@ handler that is used for all wrapper functions that follow it. Unless
there is a well-defined (and simple) error handling mechanism in place, there is a well-defined (and simple) error handling mechanism in place,
defining one universal exception handler may be unwieldy and result defining one universal exception handler may be unwieldy and result
in excessive code bloat since the handler is inlined into each wrapper function. in excessive code bloat since the handler is inlined into each wrapper function.
<p>
<p>
To fix this, you can be more selective about how you use the To fix this, you can be more selective about how you use the
<tt>%exception</tt> directive. One approach is to only place it around <tt>%exception</tt> directive. One approach is to only place it around
critical pieces of code. For example: critical pieces of code. For example:
</p>
<p> <blockquote><pre>
<blockquote><pre>%exception { %exception {
... your exception handler ... ... your exception handler ...
} }
/* Define critical operations that can throw exceptions here */ /* Define critical operations that can throw exceptions here */
@ -291,6 +306,7 @@ in the specified class as well as for identically named functions appearing in d
<p> <p>
<tt>%exception</tt> can even be used to pinpoint a precise declaration when overloading is used. For example: <tt>%exception</tt> can even be used to pinpoint a precise declaration when overloading is used. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -347,17 +363,18 @@ was intended to be a mechanism for pinpointing specific
declarations. However, it never really worked that well and the new declarations. However, it never really worked that well and the new
%exception directive is much better. %exception directive is much better.
<a name="n7"></a><H3>9.1.5 Using The SWIG exception library</H3> <H3><a name="Customization_nn7"></a>11.1.5 Using The SWIG exception library</H3>
<p>
The <tt>exception.i</tt> library file provides support for creating The <tt>exception.i</tt> library file provides support for creating
language independent exceptions in your interfaces. To use it, simply language independent exceptions in your interfaces. To use it, simply
put an "<tt>%include exception.i</tt>" in your interface file. This put an "<tt>%include exception.i</tt>" in your interface file. This
creates a function<tt> SWIG_exception()</tt> that can be used to raise creates a function<tt> SWIG_exception()</tt> that can be used to raise
common scripting language exceptions in a portable manner. For example :<p> common scripting language exceptions in a portable manner. For example :</p>
<p> <blockquote><pre>
<blockquote><pre>// Language independent exception handler // Language independent exception handler
%include exception.i %include exception.i
%exception { %exception {
@ -376,12 +393,13 @@ common scripting language exceptions in a portable manner. For example :<p>
</pre></blockquote> </pre></blockquote>
<p>
As arguments, <tt>SWIG_exception()</tt> takes an error type code (an As arguments, <tt>SWIG_exception()</tt> takes an error type code (an
integer) and an error message string. The currently supported error integer) and an error message string. The currently supported error
types are :<p> types are :</p>
<p> <blockquote><pre>
<blockquote><pre>SWIG_MemoryError SWIG_MemoryError
SWIG_IOError SWIG_IOError
SWIG_RuntimeError SWIG_RuntimeError
SWIG_IndexError SWIG_IndexError
@ -393,14 +411,14 @@ SWIG_ValueError
SWIG_SystemError SWIG_SystemError
SWIG_UnknownError SWIG_UnknownError
</pre></blockquote> </pre></blockquote>
<p>
<p>
Since the <tt>SWIG_exception()</tt> function is defined at the C-level Since the <tt>SWIG_exception()</tt> function is defined at the C-level
it can be used elsewhere in SWIG. This includes typemaps and helper it can be used elsewhere in SWIG. This includes typemaps and helper
functions. functions.
</p>
<a name="ownership"> <H2><a name="ownership"></a>11.2 Object ownership and %newobject</H2>
<a name="n8"></a><H2>9.2 Object ownership and %newobject</H2>
A common problem in some applications is managing proper ownership of objects. For A common problem in some applications is managing proper ownership of objects. For
@ -424,6 +442,7 @@ returned object was newly created).
<p> <p>
To fix this, you can provide an extra hint to the code generator using To fix this, you can provide an extra hint to the code generator using
the <tt>%newobject</tt> directive. For example: the <tt>%newobject</tt> directive. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -455,6 +474,7 @@ Closely related to <tt>%newobject</tt> is a special typemap. The "newfree" type
can be used to deallocate a newly allocated return value. It is only available on can be used to deallocate a newly allocated return value. It is only available on
methods for which <tt>%newobject</tt> has been applied and is commonly used to clean-up string methods for which <tt>%newobject</tt> has been applied and is commonly used to clean-up string
results. For example: results. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -473,6 +493,7 @@ The "newfree" typemap in the example simply releases this memory.
<p> <p>
<b>Compatibility note:</b> Previous versions of SWIG had a special <tt>%new</tt> directive. However, unlike <tt>%newobject</tt>, <b>Compatibility note:</b> Previous versions of SWIG had a special <tt>%new</tt> directive. However, unlike <tt>%newobject</tt>,
it only applied to the next declaration. For example: it only applied to the next declaration. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -485,6 +506,7 @@ For now this is still supported but is deprecated.
<p> <p>
<b>How to shoot yourself in the foot:</b> The <tt>%newobject</tt> directive is not a declaration modifier like the old <b>How to shoot yourself in the foot:</b> The <tt>%newobject</tt> directive is not a declaration modifier like the old
<tt>%new</tt> directive. Don't write code like this: <tt>%new</tt> directive. Don't write code like this:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -494,8 +516,7 @@ char *strdup(const char *s);
</blockquote> </blockquote>
The results might not be what you expect. The results might not be what you expect.
<a name="features"></a> <H2><a name="features"></a>11.3 Features and the %feature directive</H2>
<a name="n9"></a><H2>9.3 Features and the %feature directive</H2>
Both <tt>%exception</tt> and <tt>%newobject</tt> are examples of a Both <tt>%exception</tt> and <tt>%newobject</tt> are examples of a
@ -539,10 +560,12 @@ When a feature is defined, it is given a name and a value. Most commonly, the
value is supplied after the declaration name as shown for the <tt>"except"</tt> value is supplied after the declaration name as shown for the <tt>"except"</tt>
example above. However, if the feature is simple, a value might be supplied example above. However, if the feature is simple, a value might be supplied
as an extra argument as shown for the <tt>"new"</tt> feature. as an extra argument as shown for the <tt>"new"</tt> feature.
</p>
<p> <p>
A feature stays in effect until it is explicitly disabled. A feature is disabled by A feature stays in effect until it is explicitly disabled. A feature is disabled by
supplying a <tt>%feature</tt> directive with no value. For example: supplying a <tt>%feature</tt> directive with no value. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -554,6 +577,7 @@ supplying a <tt>%feature</tt> directive with no value. For example:
If no declaration name is given, a global feature is defined. This feature is then If no declaration name is given, a global feature is defined. This feature is then
attached to <em>every</em> declaration that follows. This is how global exception handlers attached to <em>every</em> declaration that follows. This is how global exception handlers
are defined. For example: are defined. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -618,10 +642,10 @@ In the following example, <tt>MyExceptionClass</tt> is the name of the Java clas
Further details can be obtained from the <a href="Java.html#exception_handling">Java exception handling</a> section. Further details can be obtained from the <a href="Java.html#exception_handling">Java exception handling</a> section.
<p> <p>
As can be seen, the intended use for the <tt>%feature</tt> directive is as a highly flexible customization mechanism that can be used to annotate As can be seen, the intended use for the <tt>%feature</tt> directive is as a highly flexible customization mechanism that can be used to annotate
declarations with additional information for use by specific target language modules. Another example is declarations with additional information for use by specific target language modules. Another example is
in the Python module. You might use <tt>%feature</tt> to rewrite proxy/shadow class code as follows: in the Python module. You might use <tt>%feature</tt> to rewrite proxy/shadow class code as follows:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -647,7 +671,7 @@ public:
Further details of <tt>%feature</tt> usage is described in the documentation for specific language modules. Further details of <tt>%feature</tt> usage is described in the documentation for specific language modules.
<p><hr> <hr>
<address>SWIG 1.3 - Last Modified : June 28, 2004</address> <address>SWIG 1.3 - Last Modified : June 28, 2004</address>
</body> </body>

File diff suppressed because it is too large Load diff

View file

@ -7,35 +7,35 @@
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>16 SWIG and Guile</H1> <H1><a name="Guile"></a>18 SWIG and Guile</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">Meaning of "Module"</a> <li><a href="#Guile_nn2">Meaning of "Module"</a>
<li><a href="#n3">Using the SCM or GH Guile API</a> <li><a href="#Guile_nn3">Using the SCM or GH Guile API</a>
<li><a href="#n4">Linkage</a> <li><a href="#Guile_nn4">Linkage</a>
<ul> <ul>
<li><a href="#n5">Simple Linkage</a> <li><a href="#Guile_nn5">Simple Linkage</a>
<li><a href="#n6">Passive Linkage</a> <li><a href="#Guile_nn6">Passive Linkage</a>
<li><a href="#n7">Native Guile Module Linkage</a> <li><a href="#Guile_nn7">Native Guile Module Linkage</a>
<li><a href="#n8">Old Auto-Loading Guile Module Linkage</a> <li><a href="#Guile_nn8">Old Auto-Loading Guile Module Linkage</a>
<li><a href="#n9">Hobbit4D Linkage</a> <li><a href="#Guile_nn9">Hobbit4D Linkage</a>
<li><a href="#n10">General Remarks on Multiple SWIG Modules</a> <li><a href="#Guile_nn10">General Remarks on Multiple SWIG Modules</a>
</ul> </ul>
<li><a href="#n11">Underscore Folding</a> <li><a href="#Guile_nn11">Underscore Folding</a>
<li><a href="#n12">Typemaps</a> <li><a href="#Guile_nn12">Typemaps</a>
<li><a href="#n13">Representation of pointers as smobs</a> <li><a href="#Guile_nn13">Representation of pointers as smobs</a>
<ul> <ul>
<li><a href="#n14">GH Smobs</a> <li><a href="#Guile_nn14">GH Smobs</a>
<li><a href="#n15">SCM Smobs</a> <li><a href="#Guile_nn15">SCM Smobs</a>
<li><a href="#n16">Garbage Collection</a> <li><a href="#Guile_nn16">Garbage Collection</a>
</ul> </ul>
<li><a href="#n17">Exception Handling</a> <li><a href="#Guile_nn17">Exception Handling</a>
<li><a href="#n18">Procedure documentation</a> <li><a href="#Guile_nn18">Procedure documentation</a>
<li><a href="#n19">Procedures with setters</a> <li><a href="#Guile_nn19">Procedures with setters</a>
<li><a href="#n20">GOOPS Shadow Classes</a> <li><a href="#Guile_nn20">GOOPS Shadow Classes</a>
<ul> <ul>
<li><a href="#n21">Naming Issues</a> <li><a href="#Guile_nn21">Naming Issues</a>
<li><a href="#n22">Linking</a> <li><a href="#Guile_nn22">Linking</a>
</ul> </ul>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -45,7 +45,7 @@
<p> <p>
This section details guile-specific support in SWIG. This section details guile-specific support in SWIG.
<a name="n2"></a><H2>16.1 Meaning of "Module"</H2> <H2><a name="Guile_nn2"></a>18.1 Meaning of "Module"</H2>
<p> <p>
@ -53,13 +53,13 @@ There are three different concepts of "module" involved, defined
separately for SWIG, Guile, and Libtool. To avoid horrible confusion, separately for SWIG, Guile, and Libtool. To avoid horrible confusion,
we explicitly prefix the context, e.g., "guile-module". we explicitly prefix the context, e.g., "guile-module".
<a name="n3"></a><H2>16.2 Using the SCM or GH Guile API</H2> <H2><a name="Guile_nn3"></a>18.2 Using the SCM or GH Guile API</H2>
<p>The guile module can currently export wrapper files that use the guile GH interface or the <p>The guile module can currently export wrapper files that use the guile GH interface or the
SCM interface. This is controlled by an argument passed to swig. The "-gh" argument causes swig SCM interface. This is controlled by an argument passed to swig. The "-gh" argument causes swig
to output GH code, and the "-scm" argument causes swig to output SCM code. Right now the "-gh" argument to output GH code, and the "-scm" argument causes swig to output SCM code. Right now the "-gh" argument
is the default. The "-scm" wrapper generation assumes a guile version >= 1.6 and has several advantages over is the default. The "-scm" wrapper generation assumes a guile version &gt;= 1.6 and has several advantages over
the "-gh" wrapper generation including garbage collection and GOOPS support. the "-gh" wrapper generation including garbage collection and GOOPS support.
The "-gh" wrapper generation can be used for older versions of guile. Thus eventually The "-gh" wrapper generation can be used for older versions of guile. Thus eventually
the guile GH wrapper code generation will be depreciated (as guile 1.6 and above become more common) and the the guile GH wrapper code generation will be depreciated (as guile 1.6 and above become more common) and the
@ -101,7 +101,7 @@ for the specific API. Currently only the guile language module has created a ma
but there is no reason other languages (like mzscheme or chicken) couldn't also use this. but there is no reason other languages (like mzscheme or chicken) couldn't also use this.
If that happens, there is A LOT less code duplication in the standard typemaps.</p> If that happens, there is A LOT less code duplication in the standard typemaps.</p>
<a name="n4"></a><H2>16.3 Linkage</H2> <H2><a name="Guile_nn4"></a>18.3 Linkage</H2>
<p> <p>
@ -109,7 +109,7 @@ Guile support is complicated by a lack of user community cohesiveness,
which manifests in multiple shared-library usage conventions. A set of which manifests in multiple shared-library usage conventions. A set of
policies implementing a usage convention is called a <b>linkage</b>. policies implementing a usage convention is called a <b>linkage</b>.
<a name="n5"></a><H3>16.3.1 Simple Linkage</H3> <H3><a name="Guile_nn5"></a>18.3.1 Simple Linkage</H3>
The default linkage is the simplest; nothing special is done. In this The default linkage is the simplest; nothing special is done. In this
@ -170,6 +170,8 @@ Since SWIG doesn't know how
to load your extension module (with <code>dynamic-link</code> or to load your extension module (with <code>dynamic-link</code> or
<code>load-extension</code>), you need to supply this <code>load-extension</code>), you need to supply this
information by including a directive like this in the interface file: information by including a directive like this in the interface file:
</p>
<blockquote> <blockquote>
<pre> <pre>
%scheme %{ (load-extension "./example.so" "SWIG_init") %} %scheme %{ (load-extension "./example.so" "SWIG_init") %}
@ -185,7 +187,7 @@ placed between the <code>define-module</code> form and the
<code>SWIG_init</code> via a preprocessor define to avoid symbol <code>SWIG_init</code> via a preprocessor define to avoid symbol
clashes. For this case, however, passive linkage is available. clashes. For this case, however, passive linkage is available.
<a name="n6"></a><H3>16.3.2 Passive Linkage</H3> <H3><a name="Guile_nn6"></a>18.3.2 Passive Linkage</H3>
<p>Passive linkage is just like simple linkage, but it generates an <p>Passive linkage is just like simple linkage, but it generates an
@ -195,7 +197,7 @@ package name (see below).
<p>You should use passive linkage rather than simple linkage when you <p>You should use passive linkage rather than simple linkage when you
are using multiple modules. are using multiple modules.
<a name="n7"></a><H3>16.3.3 Native Guile Module Linkage</H3> <H3><a name="Guile_nn7"></a>18.3.3 Native Guile Module Linkage</H3>
<p>SWIG can also generate wrapper code that does all the Guile module <p>SWIG can also generate wrapper code that does all the Guile module
@ -236,7 +238,7 @@ Newer Guile versions have a shorthand procedure for this:
</blockquote> </blockquote>
</ul> </ul>
<a name="n8"></a><H3>16.3.4 Old Auto-Loading Guile Module Linkage</H3> <H3><a name="Guile_nn8"></a>18.3.4 Old Auto-Loading Guile Module Linkage</H3>
<p>Guile used to support an autoloading facility for object-code <p>Guile used to support an autoloading facility for object-code
@ -262,7 +264,7 @@ option, SWIG generates an exported module initialization function with
an appropriate name. an appropriate name.
<a name="n9"></a><H3>16.3.5 Hobbit4D Linkage</H3> <H3><a name="Guile_nn9"></a>18.3.5 Hobbit4D Linkage</H3>
<p> <p>
@ -271,6 +273,7 @@ libraries suitable for use by hobbit's <code>(hobbit4d link)</code>
guile module. This is called the "hobbit" linkage, and requires also guile module. This is called the "hobbit" linkage, and requires also
using the "-package" command line option to set the part of the module using the "-package" command line option to set the part of the module
name before the last symbol. For example, both command lines: name before the last symbol. For example, both command lines:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -279,13 +282,15 @@ swig -guile -package my/lib -module foo foo.i
</pre> </pre>
</blockquote> </blockquote>
<p>
would create module <code>(my lib foo)</code> (assuming in the first would create module <code>(my lib foo)</code> (assuming in the first
case foo.i declares the module to be "foo"). The installed files are case foo.i declares the module to be "foo"). The installed files are
my/lib/libfoo.so.X.Y.Z and friends. This scheme is still very my/lib/libfoo.so.X.Y.Z and friends. This scheme is still very
experimental; the (hobbit4d link) conventions are not well understood. experimental; the (hobbit4d link) conventions are not well understood.
</p>
<a name="n10"></a><H3>16.3.6 General Remarks on Multiple SWIG Modules</H3> <H3><a name="Guile_nn10"></a>18.3.6 General Remarks on Multiple SWIG Modules</H3>
If you want to use multiple SWIG modules, they have to share some If you want to use multiple SWIG modules, they have to share some
@ -298,9 +303,9 @@ The remaining modules must be compiled with the
with the runtime code. You could create an empty swig module and use that with the runtime code. You could create an empty swig module and use that
to generate the runtime code instead of placing the runtime code into a to generate the runtime code instead of placing the runtime code into a
module with code that is being wrapped. See the module with code that is being wrapped. See the
<a href="#Modules.html">Working with Modules</a> chapter for further details. <a href="Modules.html#Modules">Working with Modules</a> chapter for further details.
<a name="n11"></a><H2>16.4 Underscore Folding</H2> <H2><a name="Guile_nn11"></a>18.4 Underscore Folding</H2>
<p> <p>
@ -312,7 +317,7 @@ complained so far.
<code>%rename</code> to specify the Guile name of the wrapped <code>%rename</code> to specify the Guile name of the wrapped
functions and variables (see CHANGES). functions and variables (see CHANGES).
<a name="n12"></a><H2>16.5 Typemaps</H2> <H2><a name="Guile_nn12"></a>18.5 Typemaps</H2>
<p> <p>
@ -343,18 +348,21 @@ By default, if more than one value is to
be returned, a list of the values is created and returned; to switch be returned, a list of the values is created and returned; to switch
back to this behavior, use back to this behavior, use
<blockquote> <blockquote>
<pre>%values_as_list;</pre> <pre>
%values_as_list;</pre>
</blockquote> </blockquote>
<li><em>Multiple values as vectors.</em> <li><em>Multiple values as vectors.</em>
By issuing By issuing
<blockquote> <blockquote>
<pre>%values_as_vector;</pre> <pre>
%values_as_vector;</pre>
</blockquote> </blockquote>
vectors instead of lists will be used. vectors instead of lists will be used.
<li><em>Multiple values for multiple-value continuations.</em> <li><em>Multiple values for multiple-value continuations.</em>
<strong>This is the most elegant way.</strong> By issuing <strong>This is the most elegant way.</strong> By issuing
<blockquote> <blockquote>
<pre>%multiple_values;</pre> <pre>
%multiple_values;</pre>
</blockquote> </blockquote>
multiple values are passed to the multiple-value multiple values are passed to the multiple-value
continuation, as created by <code>call-with-values</code> or the continuation, as created by <code>call-with-values</code> or the
@ -375,7 +383,7 @@ In <code><var>body</var></code>, the first result of
</ul> </ul>
See also the "multivalue" example. See also the "multivalue" example.
<a name="n13"></a><H2>16.6 Representation of pointers as smobs</H2> <H2><a name="Guile_nn13"></a>18.6 Representation of pointers as smobs</H2>
<p> <p>
@ -392,11 +400,11 @@ upper half of the CAR is read from this struct.
To get the pointer represented by a smob, the wrapper code calls the To get the pointer represented by a smob, the wrapper code calls the
function <code>SWIG_ConvertPtr()</code>, passing a pointer to a struct function <code>SWIG_ConvertPtr()</code>, passing a pointer to a struct
representing the expected pointer type. See also representing the expected pointer type. See also
<a href="Typemaps.html#n41">Section 8.8 The run-time type checker</a>. <a href="Typemaps.html#runtime_type_checker">The run-time type checker</a>.
If the Scheme object passed was not a SWIG smob representing a compatible If the Scheme object passed was not a SWIG smob representing a compatible
pointer, a <code>wrong-type-arg</code> exception is raised. pointer, a <code>wrong-type-arg</code> exception is raised.
<a name="n14"></a><H3>16.6.1 GH Smobs</H3> <H3><a name="Guile_nn14"></a>18.6.1 GH Smobs</H3>
<p> <p>
@ -415,7 +423,7 @@ available. <code>SWIG_Guile_Init()</code> registers a smob type named
a table of all C pointer types seen so far, to which new types seen a table of all C pointer types seen so far, to which new types seen
are appended. The CDR stores the pointer value. are appended. The CDR stores the pointer value.
<a name="n15"></a><H3>16.6.2 SCM Smobs</H3> <H3><a name="Guile_nn15"></a>18.6.2 SCM Smobs</H3>
<p>The SCM interface (using the "-scm" argument to swig) uses common.swg. <p>The SCM interface (using the "-scm" argument to swig) uses common.swg.
@ -430,7 +438,7 @@ in the smob tag. If a generated GOOPS module has been loaded, smobs will be wra
GOOPS class.</p> GOOPS class.</p>
<a name="n16"></a><H3>16.6.3 Garbage Collection</H3> <H3><a name="Guile_nn16"></a>18.6.3 Garbage Collection</H3>
<p>Garbage collection is a feature of the new SCM interface, and it is automatically included <p>Garbage collection is a feature of the new SCM interface, and it is automatically included
@ -440,11 +448,11 @@ to the destructor for this type. The destructor is the generated wrapper around
So swig still exports a wrapper for the destructor, it just does not call scm_c_define_gsubr() for So swig still exports a wrapper for the destructor, it just does not call scm_c_define_gsubr() for
the wrapped delete function. So the only way to delete an object is from the garbage collector, since the the wrapped delete function. So the only way to delete an object is from the garbage collector, since the
delete function is not available to scripts. How swig determines if a type should be garbage collected delete function is not available to scripts. How swig determines if a type should be garbage collected
is exactly like described in <a href="Customization.html#n9"> is exactly like described in <a href="Customization.html#ownership">
Section 9.2 Object ownership and %newobject</a> in the SWIG manual. All typemaps use an $owner var, and Object ownership and %newobject</a> in the SWIG manual. All typemaps use an $owner var, and
the guile module replaces $owner with 0 or 1 depending on feature:new.</p> the guile module replaces $owner with 0 or 1 depending on feature:new.</p>
<a name="n17"></a><H2>16.7 Exception Handling</H2> <H2><a name="Guile_nn17"></a>18.7 Exception Handling</H2>
<p> <p>
@ -468,7 +476,7 @@ mapping:
The default when not specified here is to use "swig-error". The default when not specified here is to use "swig-error".
See Lib/exception.i for details. See Lib/exception.i for details.
<a name="n18"></a><H2>16.8 Procedure documentation</H2> <H2><a name="Guile_nn18"></a>18.8 Procedure documentation</H2>
<p>If invoked with the command-line option <code>-procdoc <p>If invoked with the command-line option <code>-procdoc
@ -501,7 +509,7 @@ like this:
typemap argument <code>doc</code>. See <code>Lib/guile/typemaps.i</code> for typemap argument <code>doc</code>. See <code>Lib/guile/typemaps.i</code> for
details. details.
<a name="n19"></a><H2>16.9 Procedures with setters</H2> <H2><a name="Guile_nn19"></a>18.9 Procedures with setters</H2>
<p>For global variables, SWIG creates a single wrapper procedure <p>For global variables, SWIG creates a single wrapper procedure
@ -529,7 +537,7 @@ struct members, the procedures <code>(<var>struct</var>-<var>member</var>-get
pointer)</code> and <code>(<var>struct-member</var>-set pointer pointer)</code> and <code>(<var>struct-member</var>-set pointer
value)</code> are <em>not</em> generated. value)</code> are <em>not</em> generated.
<a name="n20"></a><H2>16.10 GOOPS Shadow Classes</H2> <H2><a name="Guile_nn20"></a>18.10 GOOPS Shadow Classes</H2>
<p>SWIG can also generate classes and generic functions for use with <p>SWIG can also generate classes and generic functions for use with
@ -551,7 +559,8 @@ current directory. GOOPS support requires either passive or module linkage.</p>
<p>If <code>-emit-slot-accessors</code> is also passed as an argument, <p>If <code>-emit-slot-accessors</code> is also passed as an argument,
then the generated file will contain accessor methods for all the then the generated file will contain accessor methods for all the
slots in the classes and for global variables. The input class</p> slots in the classes and for global variables. The input class</p>
<blockquote><pre> class Foo { <blockquote><pre>
class Foo {
public: public:
Foo(int i) : a(i) {} Foo(int i) : a(i) {}
int a; int a;
@ -561,7 +570,8 @@ slots in the classes and for global variables. The input class</p>
Foo getFooPlus(int i) { return Foo(a + i); } Foo getFooPlus(int i) { return Foo(a + i); }
</pre></blockquote> </pre></blockquote>
will produce (if <code>-emit-slot-accessors</code> is not passed as a parameter) will produce (if <code>-emit-slot-accessors</code> is not passed as a parameter)
<blockquote><pre>(define-class &lt;Foo&gt; (&lt;swig&gt;) <blockquote><pre>
(define-class &lt;Foo&gt; (&lt;swig&gt;)
(a #:allocation #:swig-virtual (a #:allocation #:swig-virtual
#:slot-ref primitive:Foo-a-get #:slot-ref primitive:Foo-a-get
#:slot-set! primitive:Foo-a-set) #:slot-set! primitive:Foo-a-set)
@ -579,7 +589,8 @@ will produce (if <code>-emit-slot-accessors</code> is not passed as a parameter)
(export &lt;Foo&gt; getMultBy getFooMultBy getFooPlus ) (export &lt;Foo&gt; getMultBy getFooMultBy getFooPlus )
</pre></blockquote> </pre></blockquote>
and will produce (if <code>-emit-slot-accessors</code> is passed as a parameter) and will produce (if <code>-emit-slot-accessors</code> is passed as a parameter)
<blockquote><pre>(define-class &lt;Foo&gt; (&lt;swig&gt;) <blockquote><pre>
(define-class &lt;Foo&gt; (&lt;swig&gt;)
(a #:allocation #:swig-virtual (a #:allocation #:swig-virtual
#:slot-ref primitive:Foo-a-get #:slot-ref primitive:Foo-a-get
#:slot-set! primitive:Foo-a-set #:slot-set! primitive:Foo-a-set
@ -620,7 +631,8 @@ which can then be used by this code
the future the following will be valid <code>(make &lt;Foo&gt; #:a 5 #:b 4)</code></p> the future the following will be valid <code>(make &lt;Foo&gt; #:a 5 #:b 4)</code></p>
<p>Also note that the order the declarations occur in the .i file make a difference. For example, <p>Also note that the order the declarations occur in the .i file make a difference. For example,
</p><blockquote><pre>%module test </p><blockquote><pre>
%module test
%{ #include "foo.h" %} %{ #include "foo.h" %}
@ -636,7 +648,8 @@ This is a valid SWIG file it will work as you think it will for primitive suppor
GOOPS file will be broken. Since the <code>someFunc</code> definition is parsed by SWIG before all the GOOPS file will be broken. Since the <code>someFunc</code> definition is parsed by SWIG before all the
declarations in foo.h, the generated GOOPS file will contain the definition of <code>someFunc()</code> declarations in foo.h, the generated GOOPS file will contain the definition of <code>someFunc()</code>
before the definition of &lt;Foo&gt;. The generated GOOPS file would look like before the definition of &lt;Foo&gt;. The generated GOOPS file would look like
<blockquote><pre>;;... <blockquote><pre>
;;...
(define-method (someFunc (swig_smob &lt;Foo&gt;)) (define-method (someFunc (swig_smob &lt;Foo&gt;))
(primitive:someFunc (slot-ref swig_smob 'smob))) (primitive:someFunc (slot-ref swig_smob 'smob)))
@ -652,7 +665,7 @@ before the definition of &lt;Foo&gt;. The generated GOOPS file would look like
Notice that &lt;Foo&gt; is used before it is defined. The fix is to just put the Notice that &lt;Foo&gt; is used before it is defined. The fix is to just put the
<code>%import "foo.h"</code> before the <code>%inline</code> block. <code>%import "foo.h"</code> before the <code>%inline</code> block.
<a name="n21"></a><H3>16.10.1 Naming Issues</H3> <H3><a name="Guile_nn21"></a>18.10.1 Naming Issues</H3>
<p>As you can see in the example above, there are potential naming conflicts. The default exported <p>As you can see in the example above, there are potential naming conflicts. The default exported
@ -679,18 +692,19 @@ The second generated guile-module contains all the GOOPS class definitions and i
a file named <i>module</i>.scm in the directory specified with -outdir or the current directory. a file named <i>module</i>.scm in the directory specified with -outdir or the current directory.
The name of this guile-module is the name of the The name of this guile-module is the name of the
swig-module (given on the command line or with the <code>%module</code> directive). swig-module (given on the command line or with the <code>%module</code> directive).
In the previous example, the GOOPS definitions will be in a file named Test.scm.</p><p> In the previous example, the GOOPS definitions will be in a file named Test.scm.</p>
</p><p>Because of the naming conflicts, you can't in general use both the <code>-primitive</code> and the GOOPS <p>Because of the naming conflicts, you can't in general use both the <code>-primitive</code> and the GOOPS
guile-modules at the same time. To do this, you need to rename the exported symbols from one or both guile-modules at the same time. To do this, you need to rename the exported symbols from one or both
guile-modules. For example,</p> guile-modules. For example,</p>
<blockquote><pre>(use-modules ((Test-primitive) #:renamer (symbol-prefix-proc 'primitive:))) <blockquote><pre>
(use-modules ((Test-primitive) #:renamer (symbol-prefix-proc 'primitive:)))
(use-modules ((Test) #:renamer (symbol-prefix-proc 'goops:))) (use-modules ((Test) #:renamer (symbol-prefix-proc 'goops:)))
</pre></blockquote> </pre></blockquote>
<p>TODO: Renaming class name prefixes?</p> <p>TODO: Renaming class name prefixes?</p>
<a name="n22"></a><H3>16.10.2 Linking</H3> <H3><a name="Guile_nn22"></a>18.10.2 Linking</H3>
<p>The guile-modules generated above all need to be linked together. GOOPS support requires <p>The guile-modules generated above all need to be linked together. GOOPS support requires
@ -710,18 +724,22 @@ and might conflict with names from the GOOPS guile-module (see above). Pass the
argument to solve this problem. If the <code>-exportprimitive</code> option is passed to SWIG the argument to solve this problem. If the <code>-exportprimitive</code> option is passed to SWIG the
<code>(export ...)</code> code that would be exported into the scmstub file is exported at the bottom <code>(export ...)</code> code that would be exported into the scmstub file is exported at the bottom
of the generated GOOPS guile-module. of the generated GOOPS guile-module.
The <code>%goops</code> directive should contain code to load the .so library.</li> The <code>%goops</code> directive should contain code to load the .so library.
<blockquote><pre>%goops %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
<blockquote><pre>
%goops %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
</pre></blockquote> </pre></blockquote>
Produces the following code at the top of the generated GOOPS guile-module Produces the following code at the top of the generated GOOPS guile-module
(with the <code>-package my/modules -module foo</code> command line arguments) (with the <code>-package my/modules -module foo</code> command line arguments)
<blockquote><pre>(define-module (my modules foo)) <blockquote><pre>
(define-module (my modules foo))
;; %goops directive goes here ;; %goops directive goes here
(load-extension "./foo.so" "scm_init_my_modules_foo_module") (load-extension "./foo.so" "scm_init_my_modules_foo_module")
(use-modules (oop goops) (Swig common)) (use-modules (oop goops) (Swig common))
</pre></blockquote> </pre></blockquote>
</li>
<li><b>Passive Linkage with -scmstub</b>: Here, the name of the scmstub file should be <li><b>Passive Linkage with -scmstub</b>: Here, the name of the scmstub file should be
<code>Module-primitive.scm</code> (with <i>primitive</i> replaced with whatever is given with the <code>-primsuffix</code> <code>Module-primitive.scm</code> (with <i>primitive</i> replaced with whatever is given with the <code>-primsuffix</code>
@ -730,8 +748,10 @@ which will then be added to the scmstub file.
Swig will automatically generate the line <code>(use-modules (<i>Package</i> <i>Module-primitive</i>))</code> Swig will automatically generate the line <code>(use-modules (<i>Package</i> <i>Module-primitive</i>))</code>
into the GOOPS guile-module. So if <i>Module-primitive.scm</i> is on the autoload path for guile, the into the GOOPS guile-module. So if <i>Module-primitive.scm</i> is on the autoload path for guile, the
<code>%goops</code> directive can be empty. Otherwise, the <code>%goops</code> directive should contain <code>%goops</code> directive can be empty. Otherwise, the <code>%goops</code> directive should contain
whatever code is needed to load the <i>Module-primitive.scm</i> file into guile.</li> whatever code is needed to load the <i>Module-primitive.scm</i> file into guile.
<blockquote><pre>%scheme %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
<blockquote><pre>
%scheme %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
// only include the following definition if (my modules foo) cannot // only include the following definition if (my modules foo) cannot
// be loaded automatically // be loaded automatically
%goops %{ %goops %{
@ -740,7 +760,8 @@ whatever code is needed to load the <i>Module-primitive.scm</i> file into guile.
%} %}
</pre></blockquote> </pre></blockquote>
Produces the following code at the top of the generated GOOPS guile-module Produces the following code at the top of the generated GOOPS guile-module
<blockquote><pre>(define-module (my modules foo)) <blockquote><pre>
(define-module (my modules foo))
;; %goops directive goes here (if any) ;; %goops directive goes here (if any)
(primitive-load "/path/to/foo-primitive.scm") (primitive-load "/path/to/foo-primitive.scm")
@ -751,15 +772,21 @@ Produces the following code at the top of the generated GOOPS guile-module
'primitive:))) 'primitive:)))
</pre></blockquote> </pre></blockquote>
</li>
<li><b>Module Linkage</b>: This is very similar to passive linkage with a scmstub file. <li><b>Module Linkage</b>: This is very similar to passive linkage with a scmstub file.
Swig will also automatically generate the line <code>(use-modules Swig will also automatically generate the line <code>(use-modules
(<i>Package</i> <i>Module-primitive</i>))</code> into the GOOPS guile-module. Again the <code>%goops</code> (<i>Package</i> <i>Module-primitive</i>))</code> into the GOOPS guile-module. Again the <code>%goops</code>
directive should contain whatever code is needed to get that module loaded into guile.</li> directive should contain whatever code is needed to get that module loaded into guile.
<blockquote><pre>%goops %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
<blockquote><pre>
%goops %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
</pre></blockquote> </pre></blockquote>
Produces the following code at the top of the generated GOOPS guile-module Produces the following code at the top of the generated GOOPS guile-module
<blockquote><pre>(define-module (my modules foo))
<blockquote><pre>
(define-module (my modules foo))
;; %goops directive goes here (if any) ;; %goops directive goes here (if any)
(load-extension "./foo.so" "scm_init_my_modules_foo_module") (load-extension "./foo.so" "scm_init_my_modules_foo_module")
@ -769,6 +796,7 @@ Produces the following code at the top of the generated GOOPS guile-module
'primitive:))) 'primitive:)))
</pre></blockquote> </pre></blockquote>
</li>
</ul> </ul>
<p><b>(Swig common)</b>: The generated GOOPS guile-module also imports definitions from the <p><b>(Swig common)</b>: The generated GOOPS guile-module also imports definitions from the

View file

@ -5,29 +5,29 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>1 Introduction</H1> <H1><a name="Introduction"></a>2 Introduction</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">What is SWIG?</a> <li><a href="#Introduction_nn2">What is SWIG?</a>
<li><a href="#n3">Why use SWIG?</a> <li><a href="#Introduction_nn3">Why use SWIG?</a>
<li><a href="#n4">A SWIG example</a> <li><a href="#Introduction_nn4">A SWIG example</a>
<ul> <ul>
<li><a href="#n5">SWIG interface file</a> <li><a href="#Introduction_nn5">SWIG interface file</a>
<li><a href="#n6">The swig command</a> <li><a href="#Introduction_nn6">The swig command</a>
<li><a href="#n7">Building a Perl5 module</a> <li><a href="#Introduction_nn7">Building a Perl5 module</a>
<li><a href="#n8">Building a Python module</a> <li><a href="#Introduction_nn8">Building a Python module</a>
<li><a href="#n9">Shortcuts</a> <li><a href="#Introduction_nn9">Shortcuts</a>
</ul> </ul>
<li><a href="#n10">Supported C/C++ language features</a> <li><a href="#Introduction_nn10">Supported C/C++ language features</a>
<li><a href="#n11">Non-intrusive interface building</a> <li><a href="#Introduction_nn11">Non-intrusive interface building</a>
<li><a href="#n12">Hands off code generation</a> <li><a href="#Introduction_nn12">Hands off code generation</a>
<li><a href="#n13">SWIG and freedom</a> <li><a href="#Introduction_nn13">SWIG and freedom</a>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
<a name="n2"></a><H2>1.1 What is SWIG?</H2> <H2><a name="Introduction_nn2"></a>2.1 What is SWIG?</H2>
SWIG is a software development tool that simplifies the task of SWIG is a software development tool that simplifies the task of
@ -39,7 +39,6 @@ requires no modifications to existing code and can often be used to
build a usable interface in only a few minutes. Possible applications build a usable interface in only a few minutes. Possible applications
of SWIG include: of SWIG include:
<p>
<ul> <ul>
<li>Building interpreted interfaces to existing C programs. <li>Building interpreted interfaces to existing C programs.
<li>Rapid prototyping and application development. <li>Rapid prototyping and application development.
@ -65,7 +64,7 @@ project, it is particularly well suited to software development in the
small; especially the research and development work that is commonly found small; especially the research and development work that is commonly found
in scientific and engineering projects. in scientific and engineering projects.
<a name="n3"></a><H2>1.2 Why use SWIG?</H2> <H2><a name="Introduction_nn3"></a>2.2 Why use SWIG?</H2>
As stated in the previous section, the primary purpose of SWIG is to simplify As stated in the previous section, the primary purpose of SWIG is to simplify
@ -110,7 +109,6 @@ From the standpoint of C/C++, a lot of people use SWIG because they want to brea
out of the traditional monolithic C programming model which usually results out of the traditional monolithic C programming model which usually results
in programs that resemble this: in programs that resemble this:
<p>
<ul> <ul>
<li>A collection of functions and variables that do something useful. <li>A collection of functions and variables that do something useful.
<li>A <tt>main()</tt> program that starts everything. <li>A <tt>main()</tt> program that starts everything.
@ -131,16 +129,15 @@ other. At the same time, SWIG recognizes that all applications are different.
it provides a wide variety of customization features that let you change almost it provides a wide variety of customization features that let you change almost
every aspect of the language bindings. This is the main reason why SWIG has such a large every aspect of the language bindings. This is the main reason why SWIG has such a large
user manual ;-). user manual ;-).
<p>
<a name="n4"></a><H2>1.3 A SWIG example</H2> <H2><a name="Introduction_nn4"></a>2.3 A SWIG example</H2>
The best way to illustrate SWIG is with a simple example. Consider the The best way to illustrate SWIG is with a simple example. Consider the
following C code: <p> following C code:
<p> <blockquote><pre>
<blockquote><pre>/* File : example.c */ /* File : example.c */
double My_variable = 3.0; double My_variable = 3.0;
@ -160,9 +157,9 @@ int my_mod(int n, int m) {
Suppose that you wanted to access these functions and the global Suppose that you wanted to access these functions and the global
variable <tt>My_variable</tt> from Tcl. You start by making a SWIG variable <tt>My_variable</tt> from Tcl. You start by making a SWIG
interface file as shown below (by convention, these files carry a .i interface file as shown below (by convention, these files carry a .i
suffix) : <p> suffix) :
<a name="n5"></a><H3>1.3.1 SWIG interface file</H3> <H3><a name="Introduction_nn5"></a>2.3.1 SWIG interface file</H3>
<blockquote><pre> <blockquote><pre>
@ -182,16 +179,16 @@ The interface file contains ANSI C function prototypes and variable
declarations. The <tt>%module</tt> directive defines the name of the declarations. The <tt>%module</tt> directive defines the name of the
module that will be created by SWIG. The <tt>%{,%}</tt> block module that will be created by SWIG. The <tt>%{,%}</tt> block
provides a location for inserting additional code such as C header provides a location for inserting additional code such as C header
files or additional C declarations. <p> files or additional C declarations.
<a name="n6"></a><H3>1.3.2 The swig command</H3> <H3><a name="Introduction_nn6"></a>2.3.2 The swig command</H3>
SWIG is invoked using the <tt>swig</tt> command. We can use this to SWIG is invoked using the <tt>swig</tt> command. We can use this to
build a Tcl module (under Linux) as follows :<p> build a Tcl module (under Linux) as follows :
<p> <blockquote><pre>
<blockquote><pre>unix &gt; <b>swig -tcl example.i</b> unix &gt; <b>swig -tcl example.i</b>
unix &gt; <b>gcc -c -fpic example.c example_wrap.c -I/usr/local/include</b> unix &gt; <b>gcc -c -fpic example.c example_wrap.c -I/usr/local/include</b>
unix &gt; <b>gcc -shared example.o example_wrap.o -o example.so</b> unix &gt; <b>gcc -shared example.o example_wrap.o -o example.so</b>
unix &gt; <b>tclsh</b> unix &gt; <b>tclsh</b>
@ -214,17 +211,16 @@ Tcl module has been compiled into a shared library that can be loaded
into Tcl. When loaded, Tcl can now access the functions into Tcl. When loaded, Tcl can now access the functions
and variables declared in the SWIG interface. A look at the file and variables declared in the SWIG interface. A look at the file
<tt>example_wrap.c</tt> reveals a hideous mess. However, you <tt>example_wrap.c</tt> reveals a hideous mess. However, you
almost never need to worry about it.<p> almost never need to worry about it.
<a name="n7"></a><H3>1.3.3 Building a Perl5 module</H3> <H3><a name="Introduction_nn7"></a>2.3.3 Building a Perl5 module</H3>
Now, let's turn these functions into a Perl5 module. Without making Now, let's turn these functions into a Perl5 module. Without making
any changes type the following (shown for Solaris):<p> any changes type the following (shown for Solaris):
<p> <blockquote><pre>
<p> unix &gt; <b>swig -perl5 example.i</b>
<blockquote><pre>unix &gt; <b>swig -perl5 example.i</b>
unix &gt; <b>gcc -c example.c example_wrap.c \ unix &gt; <b>gcc -c example.c example_wrap.c \
-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b> -I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b>
unix &gt; <b>ld -G example.o example_wrap.o -o example.so</b> # This is for Solaris unix &gt; <b>ld -G example.o example_wrap.o -o example.so</b> # This is for Solaris
@ -241,13 +237,13 @@ unix &gt;
</pre></blockquote> </pre></blockquote>
<a name="n8"></a><H3>1.3.4 Building a Python module</H3> <H3><a name="Introduction_nn8"></a>2.3.4 Building a Python module</H3>
Finally, let's build a module for Python (shown for Irix).<p> Finally, let's build a module for Python (shown for Irix).
<p> <blockquote><pre>
<blockquote><pre>unix &gt; <b>swig -python example.i</b> unix &gt; <b>swig -python example.i</b>
unix &gt; <b>gcc -c -fpic example.c example_wrap.c -I/usr/local/include/python2.0</b> unix &gt; <b>gcc -c -fpic example.c example_wrap.c -I/usr/local/include/python2.0</b>
unix &gt; <b>gcc -shared example.o example_wrap.o -o _example.so</b> unix &gt; <b>gcc -shared example.o example_wrap.o -o _example.so</b>
unix &gt; <b>python</b> unix &gt; <b>python</b>
@ -263,16 +259,16 @@ Type "copyright", "credits" or "license" for more information.
7.5 7.5
</pre></blockquote> </pre></blockquote>
<a name="n9"></a><H3>1.3.5 Shortcuts</H3> <H3><a name="Introduction_nn9"></a>2.3.5 Shortcuts</H3>
To the truly lazy programmer, one may wonder why we needed the extra To the truly lazy programmer, one may wonder why we needed the extra
interface file at all. As it turns out, you can often do without interface file at all. As it turns out, you can often do without
it. For example, you could also build a Perl5 module by just running it. For example, you could also build a Perl5 module by just running
SWIG on the C header file and specifying a module name as follows<p> SWIG on the C header file and specifying a module name as follows
<p> <blockquote><pre>
<blockquote><pre>unix &gt; <b>swig -perl5 -module example example.h</b> unix &gt; <b>swig -perl5 -module example example.h</b>
unix &gt; <b>gcc -c example.c example_wrap.c \ unix &gt; <b>gcc -c example.c example_wrap.c \
-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b> -I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b>
unix &gt; <b>ld -G example.o example_wrap.o -o example.so</b> unix &gt; <b>ld -G example.o example_wrap.o -o example.so</b>
@ -287,7 +283,7 @@ print $example::My_variable + 4.5, "\n";
7.5 7.5
</pre></blockquote> </pre></blockquote>
<a name="n10"></a><H2>1.4 Supported C/C++ language features</H2> <H2><a name="Introduction_nn10"></a>2.4 Supported C/C++ language features</H2>
A primary goal of the SWIG project is to make the language binding A primary goal of the SWIG project is to make the language binding
@ -323,7 +319,7 @@ wrapping simple C++ code. In fact, SWIG is able handle C++ code that
stresses the very limits of many C++ compilers. stresses the very limits of many C++ compilers.
<a name="n11"></a><H2>1.5 Non-intrusive interface building</H2> <H2><a name="Introduction_nn11"></a>2.5 Non-intrusive interface building</H2>
When used as intended, SWIG requires minimal (if any) modification to When used as intended, SWIG requires minimal (if any) modification to
@ -333,7 +329,7 @@ the C code independent of the high level interface, you can change the
interface and reuse the code in other applications. It is also interface and reuse the code in other applications. It is also
possible to support different types of interfaces depending on the application. possible to support different types of interfaces depending on the application.
<a name="n12"></a><H2>1.6 Hands off code generation</H2> <H2><a name="Introduction_nn12"></a>2.6 Hands off code generation</H2>
SWIG is designed to produce working code that needs no SWIG is designed to produce working code that needs no
@ -346,7 +342,7 @@ file. While this approach may limit flexibility for hard-core hackers,
it allows others to forget about the low-level implementation it allows others to forget about the low-level implementation
details. details.
<a name="n13"></a><H2>1.7 SWIG and freedom</H2> <H2><a name="Introduction_nn13"></a>2.7 SWIG and freedom</H2>
No, this isn't a special section on the sorry state of world politics. No, this isn't a special section on the sorry state of world politics.
@ -371,8 +367,7 @@ of the programmer's way----the last thing any developer wants to do is
to spend their time debugging the output of a tool that relies on to spend their time debugging the output of a tool that relies on
non-portable or unreliable programming features. non-portable or unreliable programming features.
<p><hr> <hr>
<address>SWIG 1.3 - Last Modified : August 10, 2002</address> <address>SWIG 1.3 - Last Modified : August 10, 2002</address>
</body> </body>
</html> </html>

File diff suppressed because it is too large Load diff

View file

@ -5,32 +5,32 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>13 SWIG library</H1> <H1><a name="Library"></a>8 SWIG library</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">The %include directive and library search path</a> <li><a href="#Library_nn2">The %include directive and library search path</a>
<li><a href="#n3">C Arrays and Pointers</a> <li><a href="#Library_nn3">C Arrays and Pointers</a>
<ul> <ul>
<li><a href="#n4">cpointer.i</a> <li><a href="#Library_nn4">cpointer.i</a>
<li><a href="#n5">carrays.i</a> <li><a href="#Library_nn5">carrays.i</a>
<li><a href="#n6">cmalloc.i</a> <li><a href="#Library_nn6">cmalloc.i</a>
<li><a href="#n7">cdata.i</a> <li><a href="#Library_nn7">cdata.i</a>
</ul> </ul>
<li><a href="#n8">C String Handling</a> <li><a href="#Library_nn8">C String Handling</a>
<ul> <ul>
<li><a href="#n9">Default string handling</a> <li><a href="#Library_nn9">Default string handling</a>
<li><a href="#n10">Passing binary data</a> <li><a href="#Library_nn10">Passing binary data</a>
<li><a href="#n11">Using %newobject to release memory</a> <li><a href="#Library_nn11">Using %newobject to release memory</a>
<li><a href="#n12">cstring.i</a> <li><a href="#Library_nn12">cstring.i</a>
</ul> </ul>
<li><a href="#n13">C++ Library</a> <li><a href="#Library_nn13">C++ Library</a>
<ul> <ul>
<li><a href="#n14">std_string.i</a> <li><a href="#Library_nn14">std_string.i</a>
<li><a href="#n15">std_vector.i</a> <li><a href="#Library_nn15">std_vector.i</a>
</ul> </ul>
<li><a href="#n16">Utility Libraries</a> <li><a href="#Library_nn16">Utility Libraries</a>
<ul> <ul>
<li><a href="#n17">exception.i</a> <li><a href="#Library_nn17">exception.i</a>
</ul> </ul>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -49,14 +49,14 @@ library files for manipulating pointers, arrays, and other structures. Most
these files are now deprecated and have been removed from the distribution. these files are now deprecated and have been removed from the distribution.
Alternative libraries provide similar functionality. Please read this chapter Alternative libraries provide similar functionality. Please read this chapter
carefully if you used the old libraries. carefully if you used the old libraries.
</p>
<a name="n2"></a><H2>13.1 The %include directive and library search path</H2> <H2><a name="Library_nn2"></a>8.1 The %include directive and library search path</H2>
Library files are included using the <tt>%include</tt> directive. Library files are included using the <tt>%include</tt> directive.
When searching for files, directories are searched in the following order: When searching for files, directories are searched in the following order:
<p>
<ul> <ul>
<li>The current directory <li>The current directory
<li>Directories specified with the <tt>-I</tt> command line option <li>Directories specified with the <tt>-I</tt> command line option
@ -64,16 +64,19 @@ When searching for files, directories are searched in the following order:
<li><tt>/usr/local/lib/swig_lib</tt> (or wherever you installed SWIG) <li><tt>/usr/local/lib/swig_lib</tt> (or wherever you installed SWIG)
<li>On Windows, SWIG also looks for the library relative to the location of <tt>swig.exe</tt>. <li>On Windows, SWIG also looks for the library relative to the location of <tt>swig.exe</tt>.
</ul> </ul>
<p>
<p>
Within each directory, SWIG first looks for a subdirectory corresponding to a target language (e.g., <tt>python</tt>, Within each directory, SWIG first looks for a subdirectory corresponding to a target language (e.g., <tt>python</tt>,
<tt>tcl</tt>, etc.). If found, SWIG will search the language specific directory first. This allows <tt>tcl</tt>, etc.). If found, SWIG will search the language specific directory first. This allows
for language-specific implementations of library files. for language-specific implementations of library files.
</p>
<p> <p>
You can override the location of the SWIG library by setting the You can override the location of the SWIG library by setting the
<tt>SWIG_LIB</tt> environment variable.<p> <tt>SWIG_LIB</tt> environment variable.
</p>
<a name="n3"></a><H2>13.2 C Arrays and Pointers</H2> <H2><a name="Library_nn3"></a>8.2 C Arrays and Pointers</H2>
This section describes library modules for manipulating low-level C arrays and pointers. This section describes library modules for manipulating low-level C arrays and pointers.
@ -83,7 +86,7 @@ used to allocate memory, manufacture pointers, dereference memory, and wrap
pointers as class-like objects. Since these functions provide direct access to pointers as class-like objects. Since these functions provide direct access to
memory, their use is potentially unsafe and you should exercise caution. memory, their use is potentially unsafe and you should exercise caution.
<a name="n4"></a><H3>13.2.1 cpointer.i</H3> <H3><a name="Library_nn4"></a>8.2.1 cpointer.i</H3>
The <tt>cpointer.i</tt> module defines macros that can be used to used The <tt>cpointer.i</tt> module defines macros that can be used to used
@ -93,11 +96,15 @@ this module is in generating pointers to primitive datatypes such as
<p> <p>
<b><tt>%pointer_functions(type,name)</tt></b> <b><tt>%pointer_functions(type,name)</tt></b>
</p>
<blockquote> <blockquote>
Generates a collection of four functions for manipulating a pointer <tt>type *</tt>: Generates a collection of four functions for manipulating a pointer <tt>type *</tt>:
<p> <p>
<tt>type *new_name()</tt> <tt>type *new_name()</tt>
</p>
<blockquote> <blockquote>
Creates a new object of type <tt>type</tt> and returns a pointer to it. In C, the Creates a new object of type <tt>type</tt> and returns a pointer to it. In C, the
object is created using <tt>calloc()</tt>. In C++, <tt>new</tt> is used. object is created using <tt>calloc()</tt>. In C++, <tt>new</tt> is used.
@ -105,6 +112,8 @@ object is created using <tt>calloc()</tt>. In C++, <tt>new</tt> is used.
<p> <p>
<tt>type *copy_name(type value)</tt> <tt>type *copy_name(type value)</tt>
</p>
<blockquote> <blockquote>
Creates a new object of type <tt>type</tt> and returns a pointer to it. Creates a new object of type <tt>type</tt> and returns a pointer to it.
An initial value is set by copying it from <tt>value</tt>. In C, the An initial value is set by copying it from <tt>value</tt>. In C, the
@ -113,18 +122,24 @@ object is created using <tt>calloc()</tt>. In C++, <tt>new</tt> is used.
<p> <p>
<tt>type *delete_name(type *obj)</tt> <tt>type *delete_name(type *obj)</tt>
</p>
<blockquote> <blockquote>
Deletes an object type <tt>type</tt>. Deletes an object type <tt>type</tt>.
</blockquote> </blockquote>
<p> <p>
<tt>void name_assign(type *obj, type value)</tt> <tt>void name_assign(type *obj, type value)</tt>
</p>
<blockquote> <blockquote>
Assigns <tt>*obj = value</tt>. Assigns <tt>*obj = value</tt>.
</blockquote> </blockquote>
<p> <p>
<tt>type name_value(type *obj)</tt> <tt>type name_value(type *obj)</tt>
</p>
<blockquote> <blockquote>
Returns the value of <tt>*obj</tt>. Returns the value of <tt>*obj</tt>.
</blockquote> </blockquote>
@ -151,18 +166,19 @@ Now, in Python:
<blockquote> <blockquote>
<pre> <pre>
>>> import example &gt;&gt;&gt; import example
>>> c = example.new_intp() # Create an "int" for storing result &gt;&gt;&gt; c = example.new_intp() # Create an "int" for storing result
>>> example.add(3,4,c) # Call function &gt;&gt;&gt; example.add(3,4,c) # Call function
>>> example.intp_value(c) # Dereference &gt;&gt;&gt; example.intp_value(c) # Dereference
7 7
>>> example.delete_intp(c) # Delete &gt;&gt;&gt; example.delete_intp(c) # Delete
</pre> </pre>
</blockquote> </blockquote>
<p>
<p> <p>
<b><tt>%pointer_class(type,name)</tt></b> <b><tt>%pointer_class(type,name)</tt></b>
</p>
<blockquote> <blockquote>
Wraps a pointer of <tt>type *</tt> inside a class-based interface. This Wraps a pointer of <tt>type *</tt> inside a class-based interface. This
interface is as follows: interface is as follows:
@ -190,10 +206,14 @@ the "class" may be transparently passed to any function that expects the pointe
<p> <p>
If the target language does not support proxy classes, the use of this macro will produce the example If the target language does not support proxy classes, the use of this macro will produce the example
same functions as <tt>%pointer_functions()</tt> macro. same functions as <tt>%pointer_functions()</tt> macro.
</p>
<p> <p>
It should be noted that the class interface does introduce a new object or wrap a pointer inside a special It should be noted that the class interface does introduce a new object or wrap a pointer inside a special
structure. Instead, the raw pointer is used directly. structure. Instead, the raw pointer is used directly.
</p>
</blockquote> </blockquote>
@ -216,10 +236,10 @@ Now, in Python (using proxy classes)
<blockquote> <blockquote>
<pre> <pre>
>>> import example &gt;&gt;&gt; import example
>>> c = example.intp() # Create an "int" for storing result &gt;&gt;&gt; c = example.intp() # Create an "int" for storing result
>>> example.add(3,4,c) # Call function &gt;&gt;&gt; example.add(3,4,c) # Call function
>>> c.value() # Dereference &gt;&gt;&gt; c.value() # Dereference
7 7
</pre> </pre>
</blockquote> </blockquote>
@ -228,9 +248,10 @@ Of the two macros, <tt>%pointer_class</tt> is probably the most convenient when
pointers. This is because the pointers are access like objects and they can be easily garbage collected pointers. This is because the pointers are access like objects and they can be easily garbage collected
(destruction of the pointer object destroys the underlying object). (destruction of the pointer object destroys the underlying object).
<p>
<p> <p>
<b><tt>%pointer_cast(type1, type2, name)</tt></b> <b><tt>%pointer_cast(type1, type2, name)</tt></b>
</p>
<blockquote> <blockquote>
Creates a casting function that converts <tt>type1</tt> to <tt>type2</tt>. The name of the function is <tt>name</tt>. Creates a casting function that converts <tt>type1</tt> to <tt>type2</tt>. The name of the function is <tt>name</tt>.
For example: For example:
@ -247,11 +268,13 @@ In this example, the function <tt>int_to_uint()</tt> would be used to cast type
<p> <p>
<b>Note:</b> None of these macros can be used to safely work with strings (<tt>char *</tt> or <tt>char **</tt>). <b>Note:</b> None of these macros can be used to safely work with strings (<tt>char *</tt> or <tt>char **</tt>).
</p>
<P> <P>
<b>Note:</b> When working with simple pointers, typemaps can often be used to provide more seamless operation. <b>Note:</b> When working with simple pointers, typemaps can often be used to provide more seamless operation.
</p>
<a name="n5"></a><H3>13.2.2 carrays.i</H3> <H3><a name="Library_nn5"></a>8.2.2 carrays.i</H3>
This module defines macros that assist in wrapping ordinary C pointers as arrays. This module defines macros that assist in wrapping ordinary C pointers as arrays.
@ -261,11 +284,15 @@ raw C array data.
<p> <p>
<b><tt>%array_functions(type,name)</tt></b> <b><tt>%array_functions(type,name)</tt></b>
</p>
<blockquote> <blockquote>
Creates four functions. Creates four functions.
<p> <p>
<tt>type *new_name(int nelements)</tt> <tt>type *new_name(int nelements)</tt>
</p>
<blockquote> <blockquote>
Creates a new array of objects of type <tt>type</tt>. In C, the array is allocated using Creates a new array of objects of type <tt>type</tt>. In C, the array is allocated using
<tt>calloc()</tt>. In C++, <tt>new []</tt> is used. <tt>calloc()</tt>. In C++, <tt>new []</tt> is used.
@ -273,18 +300,24 @@ Creates a new array of objects of type <tt>type</tt>. In C, the array is alloc
<p> <p>
<tt>type *delete_name(type *ary)</tt> <tt>type *delete_name(type *ary)</tt>
</p>
<blockquote> <blockquote>
Deletes an array. In C, <tt>free()</tt> is used. In C++, <tt>delete []</tt> is used. Deletes an array. In C, <tt>free()</tt> is used. In C++, <tt>delete []</tt> is used.
</blockquote> </blockquote>
<p> <p>
<tt>type name_getitem(type *ary, int index)</tt> <tt>type name_getitem(type *ary, int index)</tt>
</p>
<blockquote> <blockquote>
Returns the value <tt>ary[index]</tt>. Returns the value <tt>ary[index]</tt>.
</blockquote> </blockquote>
<p> <p>
<tt>void name_setitem(type *ary, int index, type value)</tt> <tt>void name_setitem(type *ary, int index, type value)</tt>
</p>
<blockquote> <blockquote>
Assigns <tt>ary[index] = value</tt>. Assigns <tt>ary[index] = value</tt>.
</blockquote> </blockquote>
@ -296,6 +329,7 @@ should not correspond to any other name used in the interface file.
<p> <p>
Here is an example of <tt>%array_functions()</tt>. Suppose you had a Here is an example of <tt>%array_functions()</tt>. Suppose you had a
function like this: function like this:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -333,8 +367,6 @@ delete_doubleArray(a) # Destroy array
</pre> </pre>
</blockquote> </blockquote>
<p>
<p>
<b><tt>%array_class(type,name)</tt></b> <b><tt>%array_class(type,name)</tt></b>
<blockquote> <blockquote>
Wraps a pointer of <tt>type *</tt> inside a class-based interface. This Wraps a pointer of <tt>type *</tt> inside a class-based interface. This
@ -365,6 +397,7 @@ it can be transparently passed to any function that expects the pointer.
<p> <p>
When combined with proxy classes, the <tt>%array_class()</tt> macro can be especially useful. When combined with proxy classes, the <tt>%array_class()</tt> macro can be especially useful.
For example: For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -392,12 +425,14 @@ example.print_array(c) # Pass to C
<b>Note:</b> These macros do not encapsulate C arrays inside a special data structure <b>Note:</b> These macros do not encapsulate C arrays inside a special data structure
or proxy. There is no bounds checking or safety of any kind. If you want this, or proxy. There is no bounds checking or safety of any kind. If you want this,
you should consider using a special array object rather than a bare pointer. you should consider using a special array object rather than a bare pointer.
</p>
<p> <p>
<b>Note:</b> <tt>%array_functions()</tt> and <tt>%array_class()</tt> should not be <b>Note:</b> <tt>%array_functions()</tt> and <tt>%array_class()</tt> should not be
used with types of <tt>char</tt> or <tt>char *</tt>. used with types of <tt>char</tt> or <tt>char *</tt>.
</p>
<a name="n6"></a><H3>13.2.3 cmalloc.i</H3> <H3><a name="Library_nn6"></a>8.2.3 cmalloc.i</H3>
This module defines macros for wrapping the low-level C memory allocation functions This module defines macros for wrapping the low-level C memory allocation functions
@ -405,6 +440,8 @@ This module defines macros for wrapping the low-level C memory allocation functi
<p> <p>
<b><tt>%malloc(type [,name=type])</tt></b> <b><tt>%malloc(type [,name=type])</tt></b>
</p>
<blockquote> <blockquote>
Creates a wrapper around <tt>malloc()</tt> with the following prototype: Creates a wrapper around <tt>malloc()</tt> with the following prototype:
<blockquote><pre> <blockquote><pre>
@ -418,6 +455,8 @@ is not a valid identifier (e.g., "<tt>int *</tt>", "<tt>double **</tt>", etc.).
<p> <p>
<b><tt>%calloc(type [,name=type])</tt></b> <b><tt>%calloc(type [,name=type])</tt></b>
</p>
<blockquote> <blockquote>
Creates a wrapper around <tt>calloc()</tt> with the following prototype: Creates a wrapper around <tt>calloc()</tt> with the following prototype:
<blockquote><pre> <blockquote><pre>
@ -429,6 +468,8 @@ If <tt>type</tt> is <tt>void</tt>, then the size parameter <tt>sz</tt> is requir
<p> <p>
<b><tt>%realloc(type [,name=type])</tt></b> <b><tt>%realloc(type [,name=type])</tt></b>
</p>
<blockquote> <blockquote>
Creates a wrapper around <tt>realloc()</tt> with the following prototype: Creates a wrapper around <tt>realloc()</tt> with the following prototype:
<blockquote><pre> <blockquote><pre>
@ -442,6 +483,8 @@ it holds 100 integers.
<p> <p>
<b><tt>%free(type [,name=type])</tt></b> <b><tt>%free(type [,name=type])</tt></b>
</p>
<blockquote> <blockquote>
Creates a wrapper around <tt>free()</tt> with the following prototype: Creates a wrapper around <tt>free()</tt> with the following prototype:
<blockquote><pre> <blockquote><pre>
@ -452,6 +495,8 @@ void free_<em>name</em>(<em>type</em> *ptr);
<p> <p>
<b><tt>%sizeof(type [,name=type])</tt></b> <b><tt>%sizeof(type [,name=type])</tt></b>
</p>
<blockquote> <blockquote>
Creates the constant: Creates the constant:
<blockquote><pre> <blockquote><pre>
@ -462,12 +507,15 @@ Creates the constant:
<p> <p>
<b><tt>%allocators(type [,name=type])</tt></b> <b><tt>%allocators(type [,name=type])</tt></b>
</p>
<blockquote> <blockquote>
Generates wrappers for all five of the above operations. Generates wrappers for all five of the above operations.
</blockquote> </blockquote>
<p> <p>
Here is a simple example that illustrates the use of these macros: Here is a simple example that illustrates the use of these macros:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -489,27 +537,27 @@ Now, in a script:
<blockquote> <blockquote>
<pre> <pre>
>>> from example import * &gt;&gt;&gt; from example import *
>>> a = malloc_int() &gt;&gt;&gt; a = malloc_int()
>>> a &gt;&gt;&gt; a
'_000efa70_p_int' '_000efa70_p_int'
>>> free_int(a) &gt;&gt;&gt; free_int(a)
>>> b = malloc_intp() &gt;&gt;&gt; b = malloc_intp()
>>> b &gt;&gt;&gt; b
'_000efb20_p_p_int' '_000efb20_p_p_int'
>>> free_intp(b) &gt;&gt;&gt; free_intp(b)
>>> c = calloc_double(50) &gt;&gt;&gt; c = calloc_double(50)
>>> c &gt;&gt;&gt; c
'_000fab98_p_double' '_000fab98_p_double'
>>> c = realloc_double(100000) &gt;&gt;&gt; c = realloc_double(100000)
>>> free_double(c) &gt;&gt;&gt; free_double(c)
>>> print sizeof_double &gt;&gt;&gt; print sizeof_double
8 8
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
<a name="n7"></a><H3>13.2.4 cdata.i</H3> <H3><a name="Library_nn7"></a>8.2.4 cdata.i</H3>
The <tt>cdata.i</tt> module defines functions for converting raw C data to and from strings The <tt>cdata.i</tt> module defines functions for converting raw C data to and from strings
@ -520,6 +568,8 @@ in order for this to work.
<p> <p>
<b><tt>char *cdata(void *ptr, int nbytes)</tt></b> <b><tt>char *cdata(void *ptr, int nbytes)</tt></b>
</p>
<blockquote> <blockquote>
Converts <tt>nbytes</tt> of data at <tt>ptr</tt> into a string. <tt>ptr</tt> can be any Converts <tt>nbytes</tt> of data at <tt>ptr</tt> into a string. <tt>ptr</tt> can be any
pointer. pointer.
@ -527,6 +577,8 @@ pointer.
<p> <p>
<b><tt>void memmove(void *ptr, char *s)</tt></b> <b><tt>void memmove(void *ptr, char *s)</tt></b>
</p>
<blockquote> <blockquote>
Copies all of the string data in <tt>s</tt> into the memory pointed to by Copies all of the string data in <tt>s</tt> into the memory pointed to by
<tt>ptr</tt>. The string may contain embedded NULL bytes. The length of <tt>ptr</tt>. The string may contain embedded NULL bytes. The length of
@ -551,18 +603,18 @@ Python example:
<blockquote> <blockquote>
<pre> <pre>
>>> a = intArray(10) &gt;&gt;&gt; a = intArray(10)
>>> for i in range(0,10): &gt;&gt;&gt; for i in range(0,10):
... a[i] = i ... a[i] = i
>>> b = cdata(a,40) &gt;&gt;&gt; b = cdata(a,40)
>>> b &gt;&gt;&gt; b
'\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04 '\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04
\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\t' \x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\t'
>>> c = intArray(10) &gt;&gt;&gt; c = intArray(10)
>>> memmove(c,b) &gt;&gt;&gt; memmove(c,b)
>>> print c[4] &gt;&gt;&gt; print c[4]
4 4
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
@ -570,6 +622,8 @@ Since the size of data is not always known, the following macro is also defined:
<p> <p>
<b><tt>%cdata(type [,name=type])</tt></b> <b><tt>%cdata(type [,name=type])</tt></b>
</p>
<blockquote> <blockquote>
Generates the following function for extracting C data for a given type. Generates the following function for extracting C data for a given type.
<blockquote> <blockquote>
@ -583,7 +637,7 @@ char *cdata_<em>name</em>(int nitems)
<b>Note:</b> These functions provide direct access to memory and can be used to overwrite data. <b>Note:</b> These functions provide direct access to memory and can be used to overwrite data.
Clearly they are unsafe. Clearly they are unsafe.
<a name="n8"></a><H2>13.3 C String Handling</H2> <H2><a name="Library_nn8"></a>8.3 C String Handling</H2>
A common problem when working with C programs is dealing with A common problem when working with C programs is dealing with
@ -599,8 +653,9 @@ The problems (and perils) of using <tt>char *</tt> are
well-known. However, SWIG is not in the business of enforcing well-known. However, SWIG is not in the business of enforcing
morality. The modules in this section provide basic functionality morality. The modules in this section provide basic functionality
for manipulating raw C strings. for manipulating raw C strings.
</p>
<a name="n9"></a><H3>13.3.1 Default string handling</H3> <H3><a name="Library_nn9"></a>8.3.1 Default string handling</H3>
Suppose you have a C function with this prototype: Suppose you have a C function with this prototype:
@ -633,8 +688,9 @@ a <tt>char *</tt> argument points to data inside the target language, it is
<b>NOT</b> safe for a function to modify this data (doing so may corrupt the <b>NOT</b> safe for a function to modify this data (doing so may corrupt the
interpreter and lead to a crash). Furthermore, the default behavior does interpreter and lead to a crash). Furthermore, the default behavior does
not work well with binary data. Instead, strings are assumed to be NULL-terminated. not work well with binary data. Instead, strings are assumed to be NULL-terminated.
</p>
<a name="n10"></a><H3>13.3.2 Passing binary data</H3> <H3><a name="Library_nn10"></a>8.3.2 Passing binary data</H3>
If you have a function that expects binary data, If you have a function that expects binary data,
@ -660,14 +716,14 @@ Now, in the target language, you can use binary string data like this:
<blockquote> <blockquote>
<pre> <pre>
>>> s = "H\x00\x15eg\x09\x20" &gt;&gt;&gt; s = "H\x00\x15eg\x09\x20"
>>> parity(s,0) &gt;&gt;&gt; parity(s,0)
</pre> </pre>
</blockquote> </blockquote>
In the wrapper function, the passed string will be expanded to a pointer and length parameter. In the wrapper function, the passed string will be expanded to a pointer and length parameter.
<a name="n11"></a><H3>13.3.3 Using %newobject to release memory</H3> <H3><a name="Library_nn11"></a>8.3.3 Using %newobject to release memory</H3>
If you have a function that allocates memory like this, If you have a function that allocates memory like this,
@ -687,6 +743,7 @@ into a string object and the old contents ignored.
<p> <p>
To fix the memory leak, use the <tt>%newobject</tt> directive. To fix the memory leak, use the <tt>%newobject</tt> directive.
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -698,7 +755,7 @@ char *foo();
This will release the result. This will release the result.
<a name="n12"></a><H3>13.3.4 cstring.i</H3> <H3><a name="Library_nn12"></a>8.3.4 cstring.i</H3>
The <tt>cstring.i</tt> library file provides a collection of macros The <tt>cstring.i</tt> library file provides a collection of macros
@ -731,9 +788,12 @@ involving bounds checking).
<p> <p>
The macros defined in this module all expand to various combinations of The macros defined in this module all expand to various combinations of
typemaps. Therefore, the same pattern matching rules and ideas apply. typemaps. Therefore, the same pattern matching rules and ideas apply.
</p>
<p> <p>
<b>%cstring_bounded_output(parm, maxsize)</b> <b>%cstring_bounded_output(parm, maxsize)</b>
</p>
<blockquote> <blockquote>
Turns parameter <tt><em>parm</em></tt> into an output value. The Turns parameter <tt><em>parm</em></tt> into an output value. The
output string is assumed to be NULL-terminated and smaller than output string is assumed to be NULL-terminated and smaller than
@ -751,9 +811,9 @@ In the target language:
<blockquote> <blockquote>
<pre> <pre>
>>> get_path() &gt;&gt;&gt; get_path()
/home/beazley/packages/Foo/Bar /home/beazley/packages/Foo/Bar
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
@ -768,6 +828,8 @@ bytes are written, your program will crash with a buffer overflow!</b>
<p> <p>
<b>%cstring_chunk_output(parm, chunksize)</b> <b>%cstring_chunk_output(parm, chunksize)</b>
</p>
<blockquote> <blockquote>
Turns parameter <tt><em>parm</em></tt> into an output value. The Turns parameter <tt><em>parm</em></tt> into an output value. The
output string is always <tt><em>chunksize</em></tt> and may contain output string is always <tt><em>chunksize</em></tt> and may contain
@ -785,9 +847,9 @@ In the target language:
<blockquote> <blockquote>
<pre> <pre>
>>> get_packet() &gt;&gt;&gt; get_packet()
'\xa9Y:\xf6\xd7\xe1\x87\xdbH;y\x97\x7f"\xd3\x99\x14V\xec\x06\xea\xa2\x88' '\xa9Y:\xf6\xd7\xe1\x87\xdbH;y\x97\x7f"\xd3\x99\x14V\xec\x06\xea\xa2\x88'
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
@ -801,6 +863,8 @@ bytes are written, your program will crash with a buffer overflow!</b>
<p> <p>
<b>%cstring_bounded_mutable(parm, maxsize)</b> <b>%cstring_bounded_mutable(parm, maxsize)</b>
</p>
<blockquote> <blockquote>
Turns parameter <tt><em>parm</em></tt> into a mutable string argument. Turns parameter <tt><em>parm</em></tt> into a mutable string argument.
The input string is assumed to be NULL-terminated and smaller than The input string is assumed to be NULL-terminated and smaller than
@ -819,9 +883,9 @@ In the target language:
<blockquote> <blockquote>
<pre> <pre>
>>> make_upper("hello world") &gt;&gt;&gt; make_upper("hello world")
'HELLO WORLD' 'HELLO WORLD'
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
@ -837,6 +901,8 @@ written, your program will crash with a buffer overflow!</b>
<p> <p>
<b>%cstring_mutable(parm [, expansion])</b> <b>%cstring_mutable(parm [, expansion])</b>
</p>
<blockquote> <blockquote>
Turns parameter <tt><em>parm</em></tt> into a mutable string argument. Turns parameter <tt><em>parm</em></tt> into a mutable string argument.
The input string is assumed to be NULL-terminated. An optional The input string is assumed to be NULL-terminated. An optional
@ -861,11 +927,11 @@ In the target language:
<blockquote> <blockquote>
<pre> <pre>
>>> make_upper("hello world") &gt;&gt;&gt; make_upper("hello world")
'HELLO WORLD' 'HELLO WORLD'
>>> attach_header("Hello world") &gt;&gt;&gt; attach_header("Hello world")
'header: Hello world' 'header: Hello world'
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
@ -884,6 +950,8 @@ bytes, then the program will crash with a buffer overflow!</b>
<p> <p>
<b>%cstring_output_maxsize(parm, maxparm)</b> <b>%cstring_output_maxsize(parm, maxparm)</b>
</p>
<blockquote> <blockquote>
This macro is used to handle bounded character output functions where This macro is used to handle bounded character output functions where
both a <tt>char *</tt> and a maximum length parameter are provided. both a <tt>char *</tt> and a maximum length parameter are provided.
@ -902,9 +970,9 @@ In the target language:
<blockquote> <blockquote>
<pre> <pre>
>>> get_path(1024) &gt;&gt;&gt; get_path(1024)
'/home/beazley/Packages/Foo/Bar' '/home/beazley/Packages/Foo/Bar'
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
@ -918,6 +986,8 @@ into that buffer and returned as a string object.
<p> <p>
<b>%cstring_output_withsize(parm, maxparm)</b> <b>%cstring_output_withsize(parm, maxparm)</b>
</p>
<blockquote> <blockquote>
This macro is used to handle bounded character output functions where This macro is used to handle bounded character output functions where
both a <tt>char *</tt> and a pointer <tt>int *</tt> are passed. Initially, both a <tt>char *</tt> and a pointer <tt>int *</tt> are passed. Initially,
@ -938,11 +1008,11 @@ In the target language:
<blockquote> <blockquote>
<pre> <pre>
>>> get_data(1024) &gt;&gt;&gt; get_data(1024)
'x627388912' 'x627388912'
>>> get_data(1024) &gt;&gt;&gt; get_data(1024)
'xyzzy' 'xyzzy'
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
@ -954,6 +1024,8 @@ how much data is actually returned by changing the value of the <tt>maxparm</tt>
<p> <p>
<b>%cstring_output_allocate(parm, release)</b> <b>%cstring_output_allocate(parm, release)</b>
</p>
<blockquote> <blockquote>
This macro is used to return strings that are allocated within the program and This macro is used to return strings that are allocated within the program and
returned in a parameter of type <tt>char **</tt>. For example: returned in a parameter of type <tt>char **</tt>. For example:
@ -983,9 +1055,9 @@ In the target language:
<blockquote> <blockquote>
<pre> <pre>
>>> foo() &gt;&gt;&gt; foo()
'Hello world\n' 'Hello world\n'
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
</blockquote> </blockquote>
@ -993,6 +1065,8 @@ In the target language:
<p> <p>
<b>%cstring_output_allocate_size(parm, szparm, release)</b> <b>%cstring_output_allocate_size(parm, szparm, release)</b>
</p>
<blockquote> <blockquote>
This macro is used to return strings that are allocated within the program and This macro is used to return strings that are allocated within the program and
returned in two parameters of type <tt>char **</tt> and <tt>int *</tt>. For example: returned in two parameters of type <tt>char **</tt> and <tt>int *</tt>. For example:
@ -1024,9 +1098,9 @@ In the target language:
<blockquote> <blockquote>
<pre> <pre>
>>> foo() &gt;&gt;&gt; foo()
'\xa9Y:\xf6\xd7\xe1\x87\xdbH;y\x97\x7f"\xd3\x99\x14V\xec\x06\xea\xa2\x88' '\xa9Y:\xf6\xd7\xe1\x87\xdbH;y\x97\x7f"\xd3\x99\x14V\xec\x06\xea\xa2\x88'
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
@ -1053,30 +1127,31 @@ void my_get_data(char **result, int *len) {
<b>Comments:</b> <b>Comments:</b>
<ul> <ul>
<Li>Support for the <tt>cstring.i</tt> module depends on the target language. Not all <li>Support for the <tt>cstring.i</tt> module depends on the target language. Not all
SWIG modules currently support this library. SWIG modules currently support this library.
</li>
<p>
<li>Reliable handling of raw C strings is a delicate topic. There are many ways <li>Reliable handling of raw C strings is a delicate topic. There are many ways
to accomplish this in SWIG. This library provides support for a few common techniques. to accomplish this in SWIG. This library provides support for a few common techniques.
</li>
<P>
<li>If used in C++, this library uses <tt>new</tt> and <tt>delete []</tt> for memory <li>If used in C++, this library uses <tt>new</tt> and <tt>delete []</tt> for memory
allocation. If using ANSI C, the library uses <tt>malloc()</tt> and <tt>free()</tt>. allocation. If using ANSI C, the library uses <tt>malloc()</tt> and <tt>free()</tt>.
</li>
<p>
<li>Rather than manipulating <tt>char *</tt> directly, you might consider using a special string <li>Rather than manipulating <tt>char *</tt> directly, you might consider using a special string
structure or class instead. structure or class instead.
</li>
</ul> </ul>
<a name="n13"></a><H2>13.4 C++ Library</H2> <H2><a name="Library_nn13"></a>8.4 C++ Library</H2>
The library modules in this section provide access to parts of the standard C++ library. The library modules in this section provide access to parts of the standard C++ library.
All of these modules are new in SWIG-1.3.12 and are only the beginning phase of more complete All of these modules are new in SWIG-1.3.12 and are only the beginning phase of more complete
C++ library support including support for the STL. C++ library support including support for the STL.
<a name="n14"></a><H3>13.4.1 std_string.i</H3> <H3><a name="Library_nn14"></a>8.4.1 std_string.i</H3>
The <tt>std_string.i</tt> library provides typemaps for converting C++ <tt>std::string</tt> The <tt>std_string.i</tt> library provides typemaps for converting C++ <tt>std::string</tt>
@ -1088,7 +1163,7 @@ objects to and from strings in the target scripting language. For example:
%include "std_string.i" %include "std_string.i"
std::string foo(); std::string foo();
void bar(const std::string &x); void bar(const std::string &amp;x);
</pre> </pre>
</blockquote> </blockquote>
@ -1102,12 +1177,13 @@ bar("Hello World"); # Pass string as std::string
</blockquote> </blockquote>
This module only supports types <tt>std::string</tt> and This module only supports types <tt>std::string</tt> and
<tt>const std::string &</tt>. Pointers and non-const references <tt>const std::string &amp;</tt>. Pointers and non-const references
are left unmodified and returned as SWIG pointers. are left unmodified and returned as SWIG pointers.
<p> <p>
This library file is fully aware of C++ namespaces. If you export <tt>std::string</tt> or rename This library file is fully aware of C++ namespaces. If you export <tt>std::string</tt> or rename
it with a typedef, make sure you include those declarations in your interface. For example: it with a typedef, make sure you include those declarations in your interface. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -1117,14 +1193,14 @@ it with a typedef, make sure you include those declarations in your interface.
using namespace std; using namespace std;
typedef std::string String; typedef std::string String;
... ...
void foo(string s, const String &t); // std_string typemaps still applied void foo(string s, const String &amp;t); // std_string typemaps still applied
</pre> </pre>
</blockquote> </blockquote>
<b>Note:</b> The <tt>std_string</tt> library is incompatible with Perl on some platforms. <b>Note:</b> The <tt>std_string</tt> library is incompatible with Perl on some platforms.
We're looking into it. We're looking into it.
<a name="n15"></a><H3>13.4.2 std_vector.i</H3> <H3><a name="Library_nn15"></a>8.4.2 std_vector.i</H3>
The <tt>std_vector.i</tt> library provides support for the C++ <tt>vector</tt> class in the STL. The <tt>std_vector.i</tt> library provides support for the C++ <tt>vector</tt> class in the STL.
@ -1137,66 +1213,66 @@ instantiate different versions of <tt>vector</tt> for the types that you want to
%include "std_vector.i" %include "std_vector.i"
namespace std { namespace std {
%template(vectori) vector&lt;int>; %template(vectori) vector&lt;int&gt;;
%template(vectord) vector&lt;double>; %template(vectord) vector&lt;double&gt;;
}; };
</pre> </pre>
</blockquote> </blockquote>
When a template <tt>vector&lt;X></tt> is instantiated a number of things happen: When a template <tt>vector&lt;X&gt;</tt> is instantiated a number of things happen:
<ul> <ul>
<li>A class that exposes the C++ API is created in the target language . <li>A class that exposes the C++ API is created in the target language .
This can be used to create objects, invoke methods, etc. This class is This can be used to create objects, invoke methods, etc. This class is
currently a subset of the real STL vector class. currently a subset of the real STL vector class.
</li>
<p> <li>Input typemaps are defined for <tt>vector&lt;X&gt;</tt>, <tt>const vector&lt;X&gt; &amp;</tt>, and
<li>Input typemaps are defined for <tt>vector&lt;X></tt>, <tt>const vector&lt;X> &</tt>, and <tt>const vector&lt;X&gt; *</tt>. For each of these, a pointer <tt>vector&lt;X&gt; *</tt> may be passed or
<tt>const vector&lt;X> *</tt>. For each of these, a pointer <tt>vector&lt;X> *</tt> may be passed or
a native list object in the target language. a native list object in the target language.
</li>
<P> <li>An output typemap is defined for <tt>vector&lt;X&gt;</tt>. In this case, the values in the
<li>An output typemap is defined for <tt>vector&lt;X></tt>. In this case, the values in the
vector are expanded into a list object in the target language. vector are expanded into a list object in the target language.
</li>
<p> <li>For all other variations of the type, the wrappers expect to receive a <tt>vector&lt;X&gt; *</tt>
<li>For all other variations of the type, the wrappers expect to receive a <tt>vector&lt;X> *</tt>
object in the usual manner. object in the usual manner.
</li>
<P>
<li>An exception handler for <tt>std::out_of_range</tt> is defined. <li>An exception handler for <tt>std::out_of_range</tt> is defined.
</li>
<p>
<li>Optionally, special methods for indexing, item retrieval, slicing, and element assignment <li>Optionally, special methods for indexing, item retrieval, slicing, and element assignment
may be defined. This depends on the target language. may be defined. This depends on the target language.
</li>
</ul> </ul>
<p>
To illustrate the use of this library, consider the following functions: To illustrate the use of this library, consider the following functions:
<blockquote> <blockquote>
<pre> <pre>
/* File : example.h */ /* File : example.h */
#include &lt;vector> #include &lt;vector&gt;
#include &lt;algorithm> #include &lt;algorithm&gt;
#include &lt;functional> #include &lt;functional&gt;
#include &lt;numeric> #include &lt;numeric&gt;
double average(std::vector&lt;int> v) { double average(std::vector&lt;int&gt; v) {
return std::accumulate(v.begin(),v.end(),0.0)/v.size(); return std::accumulate(v.begin(),v.end(),0.0)/v.size();
} }
std::vector&lt;double> half(const std::vector&lt;double>&amp; v) { std::vector&lt;double&gt; half(const std::vector&lt;double&gt;&amp; v) {
std::vector&lt;double> w(v); std::vector&lt;double&gt; w(v);
for (unsigned int i=0; i&lt;w.size(); i++) for (unsigned int i=0; i&lt;w.size(); i++)
w[i] /= 2.0; w[i] /= 2.0;
return w; return w;
} }
void halve_in_place(std::vector&lt;double>&amp; v) { void halve_in_place(std::vector&lt;double&gt;&amp; v) {
std::transform(v.begin(),v.end(),v.begin(), std::transform(v.begin(),v.end(),v.begin(),
std::bind2nd(std::divides&lt;double>(),2.0)); std::bind2nd(std::divides&lt;double&gt;(),2.0));
} }
</pre> </pre>
</blockquote> </blockquote>
@ -1213,8 +1289,8 @@ To wrap with SWIG, you might write the following:
%include "std_vector.i" %include "std_vector.i"
// Instantiate templates used by example // Instantiate templates used by example
namespace std { namespace std {
%template(IntVector) vector&lt;int>; %template(IntVector) vector&lt;int&gt;;
%template(DoubleVector) vector&lt;double>; %template(DoubleVector) vector&lt;double&gt;;
} }
// Include the header file with above prototypes // Include the header file with above prototypes
@ -1226,38 +1302,38 @@ Now, to illustrate the behavior in the scripting interpreter, consider this Pyth
<blockquote> <blockquote>
<pre> <pre>
>>> from example import * &gt;&gt;&gt; from example import *
>>> iv = IntVector(4) # Create an vector&lt;int> &gt;&gt;&gt; iv = IntVector(4) # Create an vector&lt;int&gt;
>>> for i in range(0,4): &gt;&gt;&gt; for i in range(0,4):
... iv[i] = i ... iv[i] = i
>>> average(iv) # Call method &gt;&gt;&gt; average(iv) # Call method
1.5 1.5
>>> average([0,1,2,3]) # Call with list &gt;&gt;&gt; average([0,1,2,3]) # Call with list
1.5 1.5
>>> half([1,2,3]) # Half a list &gt;&gt;&gt; half([1,2,3]) # Half a list
(0.5,1.0,1.5) (0.5,1.0,1.5)
>>> halve_in_place([1,2,3]) # Oops &gt;&gt;&gt; halve_in_place([1,2,3]) # Oops
Traceback (most recent call last): Traceback (most recent call last):
File "&lt;stdin>", line 1, in ? File "&lt;stdin&gt;", line 1, in ?
TypeError: Type error. Expected _p_std__vectorTdouble_t TypeError: Type error. Expected _p_std__vectorTdouble_t
>>> dv = DoubleVector(4) &gt;&gt;&gt; dv = DoubleVector(4)
>>> for i in range(0,4): &gt;&gt;&gt; for i in range(0,4):
... dv[i] = i ... dv[i] = i
>>> halve_in_place(dv) # Ok &gt;&gt;&gt; halve_in_place(dv) # Ok
>>> for i in dv: &gt;&gt;&gt; for i in dv:
... print i ... print i
... ...
0.0 0.0
0.5 0.5
1.0 1.0
1.5 1.5
>>> dv[20] = 4.5 &gt;&gt;&gt; dv[20] = 4.5
Traceback (most recent call last): Traceback (most recent call last):
File "&lt;stdin>", line 1, in ? File "&lt;stdin&gt;", line 1, in ?
File "example.py", line 81, in __setitem__ File "example.py", line 81, in __setitem__
def __setitem__(*args): return apply(examplec.DoubleVector___setitem__,args) def __setitem__(*args): return apply(examplec.DoubleVector___setitem__,args)
IndexError: vector index out of range IndexError: vector index out of range
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
@ -1269,13 +1345,13 @@ make sure you include the appropriate <tt>using</tt> or typedef directives. For
%include "std_vector.i" %include "std_vector.i"
namespace std { namespace std {
%template(IntVector) vector&lt;int>; %template(IntVector) vector&lt;int&gt;;
} }
using namespace std; using namespace std;
typedef std::vector Vector; typedef std::vector Vector;
void foo(vector&lt;int> *x, const Vector &x); void foo(vector&lt;int&gt; *x, const Vector &amp;x);
</pre> </pre>
</blockquote> </blockquote>
@ -1284,19 +1360,22 @@ void foo(vector&lt;int> *x, const Vector &x);
and template partial specialization. If you are tring to wrap other C++ code with templates, you and template partial specialization. If you are tring to wrap other C++ code with templates, you
might look at the code contained in <tt>std_vector.i</tt>. Alternatively, you can show them the code might look at the code contained in <tt>std_vector.i</tt>. Alternatively, you can show them the code
if you want to make their head explode. if you want to make their head explode.
</p>
<p> <p>
<b>Note:</b> This module is defined for all SWIG target languages. However argument conversion <b>Note:</b> This module is defined for all SWIG target languages. However argument conversion
details and the public API exposed to the interpreter vary. details and the public API exposed to the interpreter vary.
</p>
<p> <p>
<b>Note:</b> <tt>std_vector.i</tt> was written by Luigi "The Amazing" Ballabio. <b>Note:</b> <tt>std_vector.i</tt> was written by Luigi "The Amazing" Ballabio.
</p>
<a name="n16"></a><H2>13.5 Utility Libraries</H2> <H2><a name="Library_nn16"></a>8.5 Utility Libraries</H2>
<a name="n17"></a><H3>13.5.1 exception.i</H3> <H3><a name="Library_nn17"></a>8.5.1 exception.i</H3>
The <tt>exception.i</tt> library provides a language-independent function for raising a run-time The <tt>exception.i</tt> library provides a language-independent function for raising a run-time
@ -1304,6 +1383,8 @@ exception in the target language.
<p> <p>
<b><tt>SWIG_exception(int code, const char *message)</tt></b> <b><tt>SWIG_exception(int code, const char *message)</tt></b>
</p>
<blockquote> <blockquote>
Raises an exception in the target language. <tt>code</tt> is one of the following symbolic Raises an exception in the target language. <tt>code</tt> is one of the following symbolic
constants: constants:
@ -1336,14 +1417,14 @@ For example:
try { try {
$action $action
} catch (std::out_of_range&amp; e) { } catch (std::out_of_range&amp; e) {
SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what())); SWIG_exception(SWIG_IndexError,const_cast&lt;char*&gt;(e.what()));
} }
} }
</pre> </pre>
</blockquote> </blockquote>
<p><hr> <hr>
<address>SWIG 1.3 - Last Modified : May 29, 2002</address> <address>SWIG 1.3 - Last Modified : May 29, 2002</address>
</body> </body>
</html> </html>

View file

@ -4,31 +4,31 @@
<title>SWIG and Modula-3</title> <title>SWIG and Modula-3</title>
</head> </head>
<body bgcolor="#FFFFFF"> <body bgcolor="#FFFFFF">
<a name="n1"></a><H1>18 SWIG and Modula-3</H1> <H1><a name="Modula3"></a>20 SWIG and Modula-3</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">Overview</a> <li><a href="#modula3_overview">Overview</a>
<li><a href="#n3">Conception</a> <li><a href="#conception">Conception</a>
<ul> <ul>
<li><a href="#n4">Interfaces to C libraries</a> <li><a href="#cinterface">Interfaces to C libraries</a>
<li><a href="#n5">Interfaces to C++ libraries</a> <li><a href="#noplan">Interfaces to C++ libraries</a>
<li><a href="#n6">No plan?</a> <li><a href="#cppinterface">No plan?</a>
</ul> </ul>
<li><a href="#n7">Preliminaries</a> <li><a href="#preliminaries">Preliminaries</a>
<ul> <ul>
<li><a href="#n8">Compilers</a> <li><a href="#compilers">Compilers</a>
<li><a href="#n9">Additional Commandline Options</a> <li><a href="#commandline">Additional Commandline Options</a>
</ul> </ul>
<li><a href="#n10">Modula-3 typemaps</a> <li><a href="#modula3_typemaps">Modula-3 typemaps</a>
<ul> <ul>
<li><a href="#n11">Inputs and outputs</a> <li><a href="#inoutparam">Inputs and outputs</a>
<li><a href="#n12">Subranges, Enumerations, Sets</a> <li><a href="#ordinals">Subranges, Enumerations, Sets</a>
<li><a href="#n13">Objects</a> <li><a href="#class">Objects</a>
<li><a href="#n14">Imports</a> <li><a href="#imports">Imports</a>
<li><a href="#n15">Exceptions</a> <li><a href="#exceptions">Exceptions</a>
<li><a href="#n16">Pragmas</a> <li><a href="#swig_pragmas">Pragmas</a>
<li><a href="#n17">Example</a> <li><a href="#typemap_example">Example</a>
<li><a href="#n18">Remarks</a> <li><a href="#remarks">Remarks</a>
</ul> </ul>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -38,12 +38,11 @@
This chapter describes SWIG's support of This chapter describes SWIG's support of
<a href="http://www.m3.org/">Modula-3</a>. <a href="http://www.m3.org/">Modula-3</a>.
You should be familiar with the You should be familiar with the
<a href="SWIG.html">basics</a> <a href="SWIG.html#SWIG">basics</a>
of SWIG, of SWIG,
especially typemaps. especially typemaps.
<a name="overview"></a> <H2><a name="modula3_overview"></a>20.1 Overview</H2>
<a name="n2"></a><H2>18.1 Overview</H2>
<p> <p>
@ -52,6 +51,8 @@ Many features are still not designed satisfyingly
and I need more discussion about the odds and ends. and I need more discussion about the odds and ends.
The Modula-3 generator was already useful for interfacing The Modula-3 generator was already useful for interfacing
to the libraries to the libraries
</p>
<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/plplot/"> <a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/plplot/">
PLPlot PLPlot
</a> </a>
@ -66,9 +67,9 @@ FFTW
The following introduction may help you The following introduction may help you
when you are uncertain about using when you are uncertain about using
the Modula-3 support or SWIG at all. the Modula-3 support or SWIG at all.
</p>
<a name="whycxx"></a>
<a name="n3"></a><DISABLED>18.1.1 Why not scripting ?</DISABLED> <a name="n3"></a><DISABLED>18.1.1 Why not scripting ?</DISABLED>
@ -80,6 +81,7 @@ to make programming life easier
by hiding machine internals from the programmer by hiding machine internals from the programmer
there are several aspects of todays scripting languages there are several aspects of todays scripting languages
that are unfavourable in my opinion. that are unfavourable in my opinion.
</p>
<p> <p>
Besides C, C++, Cluster (a Modula derivate for Amiga computers) Besides C, C++, Cluster (a Modula derivate for Amiga computers)
@ -102,8 +104,8 @@ e.g. matching regular expressions,
complex built-in datatypes like lists, dictionaries, complex built-in datatypes like lists, dictionaries,
are not advantages of the language itself are not advantages of the language itself
but can be provided by function libraries. but can be provided by function libraries.
</p>
<a name="whymodula3"></a>
<a name="n4"></a><DISABLED>18.1.2 Why Modula-3 ?</DISABLED> <a name="n4"></a><DISABLED>18.1.2 Why Modula-3 ?</DISABLED>
@ -124,6 +126,7 @@ control three languages,
namely the preprocessor, C and ++, namely the preprocessor, C and ++,
Modula-3 is made in one go Modula-3 is made in one go
and the language definition is really compact. and the language definition is really compact.
</p>
On the one hand Modula-3 can be safe On the one hand Modula-3 can be safe
(but probably less efficient) in normal modules (but probably less efficient) in normal modules
@ -138,14 +141,13 @@ requires more writing than scripting languages do.
Today if I want to safe characters Today if I want to safe characters
I prefer Haskell (similar to OCAML) - I prefer Haskell (similar to OCAML) -
it's statically typed, too. it's statically typed, too.
</p>
<a name="whycxx"></a>
<a name="n5"></a><DISABLED>18.1.3 Why C / C++ ?</DISABLED> <a name="n5"></a><DISABLED>18.1.3 Why C / C++ ?</DISABLED>
<p> <p>
Although it is no problem to write Modula-3 programs Although it is no problem to write Modula-3 programs
that performs as fast as C that performs as fast as C
most libraries are not written in Modula-3 but in C. most libraries are not written in Modula-3 but in C.
@ -153,13 +155,12 @@ Fortunately the binary interface of most function libraries
can be addressed by Modula-3. can be addressed by Modula-3.
Even more fortunately even non-C libraries may provide C header files. Even more fortunately even non-C libraries may provide C header files.
This is where SWIG becomes helpful. This is where SWIG becomes helpful.
</p>
<a name="whycxx"></a>
<a name="n6"></a><DISABLED>18.1.4 Why SWIG ?</DISABLED> <a name="n6"></a><DISABLED>18.1.4 Why SWIG ?</DISABLED>
<p> <p>
The C headers and the possibility to interface to C libraries The C headers and the possibility to interface to C libraries
still leaves the work for you still leaves the work for you
to write Modula-3 interfaces to them. to write Modula-3 interfaces to them.
@ -167,9 +168,9 @@ To make things comfortable you will also need
wrappers that convert between high-level features of Modula-3 wrappers that convert between high-level features of Modula-3
(garbage collecting, exceptions) (garbage collecting, exceptions)
and the low level of the C libraries. and the low level of the C libraries.
</p>
<p> <p>
SWIG converts C headers to Modula-3 interfaces for you. SWIG converts C headers to Modula-3 interfaces for you.
You could call the C functions without loss You could call the C functions without loss
of efficiency but it won't be joy of efficiency but it won't be joy
@ -185,6 +186,7 @@ E.g. C programmers are very creative to work-around
missing data types like (real) enumerations and sets. missing data types like (real) enumerations and sets.
You should turn such work-arounds back to the Modula-3 way You should turn such work-arounds back to the Modula-3 way
otherwise you lose static safety and consistency. otherwise you lose static safety and consistency.
</p>
<p> <p>
@ -203,9 +205,10 @@ when a new library version is released.
You will realise that writing <b>good</b> SWIG interfaces You will realise that writing <b>good</b> SWIG interfaces
is very costly and it will only amortise is very costly and it will only amortise
when considering evolving libraries. when considering evolving libraries.
</p>
<p> <p>
Without SWIG you would probably never consider Without SWIG you would probably never consider
to call C++ libraries from Modula-3. to call C++ libraries from Modula-3.
But with SWIG this is worth a consideration. But with SWIG this is worth a consideration.
@ -215,23 +218,22 @@ In fact it breaks down C++ libraries to C interfaces
which can be in turn called from Modula-3. which can be in turn called from Modula-3.
To make it complete you can hide the C interface To make it complete you can hide the C interface
with Modula-3 classes and exceptions. with Modula-3 classes and exceptions.
</p>
<p> <p>
Although SWIG does the best it can do Although SWIG does the best it can do
it can only serve as a one-way strategy. it can only serve as a one-way strategy.
That means you can use C++ libraries That means you can use C++ libraries
with Modula-3 (even with call back functions), with Modula-3 (even with call back functions),
but it's certainly not possible to smoothly but it's certainly not possible to smoothly
integrate Modula-3 code into a C / C++ project. integrate Modula-3 code into a C / C++ project.
</p>
--> -->
<a name="conception"></a> <H2><a name="conception"></a>20.2 Conception</H2>
<a name="n3"></a><H2>18.2 Conception</H2>
<a name="cinterface"></a> <H3><a name="cinterface"></a>20.2.1 Interfaces to C libraries</H3>
<a name="n4"></a><H3>18.2.1 Interfaces to C libraries</H3>
<p> <p>
@ -249,7 +251,7 @@ All you have to do is to write pieces of Modula-3 code
that SWIG puts together. that SWIG puts together.
</p> </p>
<table border> <table border summary="Modula-3 C library support">
<tr><th colspan=2>C library support integrated in Modula-3<th></tr> <tr><th colspan=2>C library support integrated in Modula-3<th></tr>
<tr> <tr>
<td>Pragma <tt>&lt;* EXTERNAL *&gt;</tt></td> <td>Pragma <tt>&lt;* EXTERNAL *&gt;</tt></td>
@ -276,7 +278,7 @@ and C's <tt>char *</tt> type.</td>
In each run of SWIG the Modula-3 part In each run of SWIG the Modula-3 part
generates several files: generates several files:
</p> </p>
<table border> <table border summary="Modula-3 generated files">
<tr> <tr>
<td>Module<tt>Raw.i3</tt></td> <td>Module<tt>Raw.i3</tt></td>
<td>Declaration of types that are equivalent to those of the C library, <td>Declaration of types that are equivalent to those of the C library,
@ -314,7 +316,7 @@ generates several files:
Here's a scheme of how the function calls to Modula-3 wrappers Here's a scheme of how the function calls to Modula-3 wrappers
a redirected to C library functions: a redirected to C library functions:
<table> <table summary="Modula-3 C library">
<tr> <tr>
<td align=center> <td align=center>
Modula-3 wrapper<br> Modula-3 wrapper<br>
@ -347,8 +349,7 @@ a redirected to C library functions:
</table> </table>
<a name="cppinterface"></a> <H3><a name="noplan"></a>20.2.2 Interfaces to C++ libraries</H3>
<a name="n5"></a><H3>18.2.2 Interfaces to C++ libraries</H3>
<p> <p>
@ -361,7 +362,7 @@ with a C interface.
Here's a scheme of how the function calls to Modula-3 wrappers Here's a scheme of how the function calls to Modula-3 wrappers
a redirected to C library functions: a redirected to C library functions:
<table> <table summary="Modula-3 C++ library">
<tr> <tr>
<td align=center> <td align=center>
Modula-3 wrapper<br> Modula-3 wrapper<br>
@ -400,6 +401,7 @@ a redirected to C library functions:
<p> <p>
Wrapping C++ libraries arises additional problems: Wrapping C++ libraries arises additional problems:
</p>
<ul> <ul>
<li> <li>
Is it sensible to wrap C++ class with Modula-3 classes? Is it sensible to wrap C++ class with Modula-3 classes?
@ -445,8 +447,7 @@ There is no C++ library I wrote a SWIG interface for,
so I'm not sure if this is possible or sensible, yet. so I'm not sure if this is possible or sensible, yet.
</p> </p>
<a name="cppinterface"></a> <H3><a name="cppinterface"></a>20.2.3 No plan?</H3>
<a name="n6"></a><H3>18.2.3 No plan?</H3>
<p> <p>
@ -468,12 +469,10 @@ and the principal type must be renamed (<tt>%typemap</tt>).
</p> </p>
<a name="preliminaries"></a> <H2><a name="preliminaries"></a>20.3 Preliminaries</H2>
<a name="n7"></a><H2>18.3 Preliminaries</H2>
<a name="compilers"></a> <H3><a name="compilers"></a>20.3.1 Compilers</H3>
<a name="n8"></a><H3>18.3.1 Compilers</H3>
There are different Modula-3 compilers around: There are different Modula-3 compilers around:
@ -485,8 +484,7 @@ may do so.
For testing examples I used Critical Mass cm3. For testing examples I used Critical Mass cm3.
<a name="commandline"></a> <H3><a name="commandline"></a>20.3.2 Additional Commandline Options</H3>
<a name="n9"></a><H3>18.3.2 Additional Commandline Options</H3>
There are some experimental command line options There are some experimental command line options
@ -494,7 +492,7 @@ that prevent SWIG from generating interface files.
Instead files are emitted that may assist you Instead files are emitted that may assist you
when writing SWIG interface files. when writing SWIG interface files.
<table> <table summary="Modula-3 specific options">
<tr> <tr>
<th>Modula-3 specific options</th> <th>Modula-3 specific options</th>
</tr> </tr>
@ -560,12 +558,10 @@ Instead generate templates for some basic typemaps.
</tr> </tr>
</table> </table>
<a name="typemaps"></a> <H2><a name="modula3_typemaps"></a>20.4 Modula-3 typemaps</H2>
<a name="n10"></a><H2>18.4 Modula-3 typemaps</H2>
<a name="inoutparam"></a> <H3><a name="inoutparam"></a>20.4.1 Inputs and outputs</H3>
<a name="n11"></a><H3>18.4.1 Inputs and outputs</H3>
<p> <p>
@ -614,7 +610,7 @@ consist of the following parts:
<li>Return values.</li> <li>Return values.</li>
</ul> </ul>
<table border> <table border summary="Modula-3 typemaps">
<tr> <tr>
<th>Typemap</th> <th>Typemap</th>
<th>Example</th> <th>Example</th>
@ -654,21 +650,21 @@ consist of the following parts:
</tr> </tr>
<tr> <tr>
<td>m3wrapinname</td> <td>m3wrapinname</td>
<td><tt></tt></td> <td></td>
<td> <td>
New name of the input argument. New name of the input argument.
</td> </td>
</tr> </tr>
<tr> <tr>
<td>m3wrapintype</td> <td>m3wrapintype</td>
<td><tt></tt></td> <td></td>
<td> <td>
Modula-3 type of the input argument. Modula-3 type of the input argument.
</td> </td>
</tr> </tr>
<tr> <tr>
<td>m3wrapindefault</td> <td>m3wrapindefault</td>
<td><tt></tt></td> <td></td>
<td> <td>
Default value of the input argument Default value of the input argument
</td> </td>
@ -682,14 +678,14 @@ consist of the following parts:
</tr> </tr>
<tr> <tr>
<td>m3wrapincheck</td> <td>m3wrapincheck</td>
<td><tt>IF Text.Length($1_name) > 10 THEN RAISE E("str too long"); END;</tt></td> <td><tt>IF Text.Length($1_name) &gt; 10 THEN RAISE E("str too long"); END;</tt></td>
<td> <td>
Check the integrity of the input value. Check the integrity of the input value.
</td> </td>
</tr> </tr>
<tr> <tr>
<td>m3wrapoutname</td> <td>m3wrapoutname</td>
<td><tt></tt></td> <td></td>
<td> <td>
Name of the <tt>RECORD</tt> field to be used for returning multiple values. Name of the <tt>RECORD</tt> field to be used for returning multiple values.
This applies to referential output arguments that shall be turned This applies to referential output arguments that shall be turned
@ -698,56 +694,56 @@ consist of the following parts:
</tr> </tr>
<tr> <tr>
<td>m3wrapouttype</td> <td>m3wrapouttype</td>
<td><tt></tt></td> <td></td>
<td> <td>
Type of the value that is returned instead of a referential output argument. Type of the value that is returned instead of a referential output argument.
</td> </td>
</tr> </tr>
<tr> <tr>
<td>m3wrapoutconv</td> <td>m3wrapoutconv</td>
<td><tt></tt></td> <td></td>
<td> <td>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>m3wrapoutcheck</td> <td>m3wrapoutcheck</td>
<td><tt></tt></td> <td></td>
<td> <td>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>m3wrapretraw</td> <td>m3wrapretraw</td>
<td><tt></tt></td> <td></td>
<td> <td>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>m3wrapretname</td> <td>m3wrapretname</td>
<td><tt></tt></td> <td></td>
<td> <td>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>m3wraprettype</td> <td>m3wraprettype</td>
<td><tt></tt></td> <td></td>
<td> <td>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>m3wrapretvar</td> <td>m3wrapretvar</td>
<td><tt></tt></td> <td></td>
<td> <td>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>m3wrapretconv</td> <td>m3wrapretconv</td>
<td><tt></tt></td> <td></td>
<td> <td>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>m3wrapretcheck</td> <td>m3wrapretcheck</td>
<td><tt></tt></td> <td></td>
<td> <td>
</td> </td>
</tr> </tr>
@ -764,16 +760,13 @@ consist of the following parts:
</table> </table>
<a name="ordinals"></a> <H3><a name="ordinals"></a>20.4.2 Subranges, Enumerations, Sets</H3>
<a name="n12"></a><H3>18.4.2 Subranges, Enumerations, Sets</H3>
<a name="class"></a> <H3><a name="class"></a>20.4.3 Objects</H3>
<a name="n13"></a><H3>18.4.3 Objects</H3>
<a name="imports"></a> <H3><a name="imports"></a>20.4.4 Imports</H3>
<a name="n14"></a><H3>18.4.4 Imports</H3>
<p> <p>
@ -806,8 +799,7 @@ IMPORT M3toC;
</pre> </pre>
<a name="exceptions"></a> <H3><a name="exceptions"></a>20.4.5 Exceptions</H3>
<a name="n15"></a><H3>18.4.5 Exceptions</H3>
Modula-3 provides another possibility Modula-3 provides another possibility
@ -825,11 +817,10 @@ contains code that may raise the exceptions <tt>OSError.E</tt>
you should declare you should declare
<tt>%typemap("m3wrapinconv:throws") blah * %{OSError.E%}</tt>. <tt>%typemap("m3wrapinconv:throws") blah * %{OSError.E%}</tt>.
<a name="swig_pragmas"></a> <H3><a name="swig_pragmas"></a>20.4.6 Pragmas</H3>
<a name="n16"></a><H3>18.4.6 Pragmas</H3>
<table border> <table border summary="Modula-3 pragmas">
<tr> <tr>
<td>unsafe</td> <td>unsafe</td>
<td><tt>%pragma(modula3) unsafe="true";</tt></td> <td><tt>%pragma(modula3) unsafe="true";</tt></td>
@ -844,8 +835,7 @@ you should declare
</tr> </tr>
</table> </table>
<a name="typemap_example"></a> <H3><a name="typemap_example"></a>20.4.7 Example</H3>
<a name="n17"></a><H3>18.4.7 Example</H3>
The generation of wrappers in Modula-3 needs very fine control The generation of wrappers in Modula-3 needs very fine control
@ -871,7 +861,7 @@ where almost everything is generated by a typemap:
BEGIN BEGIN
TRY TRY
arg1 := M3toC.SharedTtoS(str); <I>(* m3wrapinconv *)</I> arg1 := M3toC.SharedTtoS(str); <I>(* m3wrapinconv *)</I>
IF Text.Length(arg1) > 10 THEN <I>(* m3wrapincheck *)</I> IF Text.Length(arg1) &gt; 10 THEN <I>(* m3wrapincheck *)</I>
RAISE E("str too long"); RAISE E("str too long");
END; END;
<I> (* m3wrapretraw m3wrapargraw *)</I> <I> (* m3wrapretraw m3wrapargraw *)</I>
@ -887,8 +877,7 @@ where almost everything is generated by a typemap:
END Name; END Name;
</pre></blockquote> </pre></blockquote>
<a name="remarks"></a> <H3><a name="remarks"></a>20.4.8 Remarks</H3>
<a name="n18"></a><H3>18.4.8 Remarks</H3>
<ul> <ul>

View file

@ -5,13 +5,14 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>14 Working with Modules</H1> <H1><a name="Modules"></a>15 Working with Modules</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">The SWIG runtime code</a> <li><a href="#Modules_nn2">The SWIG runtime code</a>
<li><a href="#n3">Compiling Multiple SWIG modules</a> <li><a href="#Modules_nn3">Compiling Multiple SWIG modules</a>
<li><a href="#n4">A word of caution about static libraries</a> <li><a href="#Modules_nn4">A word of caution about static libraries</a>
<li><a href="#n5">References</a> <li><a href="#Modules_nn5">References</a>
<li><a href="#Modules_nn6">Reducing the wrapper file size</a>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -28,8 +29,9 @@ target language interface when it is broken up into smaller pieces.
<p> <p>
This chapter describes the problem of using SWIG in programs This chapter describes the problem of using SWIG in programs
where you want to create a collection of modules. where you want to create a collection of modules.
</p>
<a name="n2"></a><H2>14.1 The SWIG runtime code</H2> <H2><a name="Modules_nn2"></a>15.1 The SWIG runtime code</H2>
Many of SWIG's target languages generate a set of functions Many of SWIG's target languages generate a set of functions
@ -52,13 +54,15 @@ module is used in the same application, those modules often need to
share type information. This is especially true for C++ programs share type information. This is especially true for C++ programs
where SWIG must collect and share information about inheritance where SWIG must collect and share information about inheritance
relationships that cross module boundaries. relationships that cross module boundaries.
</p>
<p> <p>
To solve the problem of sharing information across modules, the To solve the problem of sharing information across modules, the
SWIG runtime functions need to be exposed in a way that allows data to SWIG runtime functions need to be exposed in a way that allows data to
be shared between modules. The next section describes how to do that. be shared between modules. The next section describes how to do that.
</p>
<a name="n3"></a><H2>14.2 Compiling Multiple SWIG modules</H2> <H2><a name="Modules_nn3"></a>15.2 Compiling Multiple SWIG modules</H2>
Suppose that you have three SWIG interface files A.i, B.i, and C.i Suppose that you have three SWIG interface files A.i, B.i, and C.i
@ -67,10 +71,12 @@ there are two approaches you can take:
<p> <p>
<b>Option 1:</b> Designate one module to provide the runtime code <b>Option 1:</b> Designate one module to provide the runtime code
</p>
<p> <p>
With this option, one of the modules is designated as providing the runtime With this option, one of the modules is designated as providing the runtime
environment. This is done with the <tt>-runtime</tt> option like this: environment. This is done with the <tt>-runtime</tt> option like this:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -99,14 +105,17 @@ on the system. On many systems, the symbols contained in dynamically loaded mod
are private. Therefore, even though module A provides the runtime code, the other modules are private. Therefore, even though module A provides the runtime code, the other modules
won't be able to find it. You'll know if this is the case if you try to load the other modules won't be able to find it. You'll know if this is the case if you try to load the other modules
and you get errors about unresolved SWIG_* functions. and you get errors about unresolved SWIG_* functions.
</p>
<p> <p>
<b>Option 2: Build a runtime library</b> <b>Option 2: Build a runtime library</b>
</p>
<p> <p>
The second way to work with multiple modules is to create a special runtime library module. The second way to work with multiple modules is to create a special runtime library module.
To do this, you first need to create an empty SWIG interface file, say swigrun.i, containing To do this, you first need to create an empty SWIG interface file, say swigrun.i, containing
just the %module directive, for example: just the %module directive, for example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -155,8 +164,9 @@ you need to link all of the modules against that library.
When you use the modules created using this technique, the runtime code will be automatically loaded When you use the modules created using this technique, the runtime code will be automatically loaded
when the modules are imported. Moreover, since all of the modules are linked against the same runtime when the modules are imported. Moreover, since all of the modules are linked against the same runtime
library, they will share that code. library, they will share that code.
</p>
<a name="n4"></a><H2>14.3 A word of caution about static libraries</H2> <H2><a name="Modules_nn4"></a>15.3 A word of caution about static libraries</H2>
When working with multiple SWIG modules, you should take care not to use static When working with multiple SWIG modules, you should take care not to use static
@ -165,27 +175,31 @@ of SWIG modules with that library, each module will get its own private copy of
into it. This is very often <b>NOT</b> what you want and it can lead to unexpected or bizarre program into it. This is very often <b>NOT</b> what you want and it can lead to unexpected or bizarre program
behavior. When working with dynamically loadable modules, you should try to work exclusively with shared libaries. behavior. When working with dynamically loadable modules, you should try to work exclusively with shared libaries.
<a name="n5"></a><H2>14.4 References</H2> <H2><a name="Modules_nn5"></a>15.4 References</H2>
Due to the complexity of working with shared libraries and multiple modules, it might be a good idea to consult Due to the complexity of working with shared libraries and multiple modules, it might be a good idea to consult
an outside reference. John Levine's "Linkers and Loaders" is highly recommended. an outside reference. John Levine's "Linkers and Loaders" is highly recommended.
<a name="n6"></a><H2>14.5 Reducing the wrapper file size</H2> <H2><a name="Modules_nn6"></a>15.5 Reducing the wrapper file size</H2>
<p>
Using multiple modules with the <tt>%import</tt> directive is the most common approach to modularising large projects. Using multiple modules with the <tt>%import</tt> directive is the most common approach to modularising large projects.
In this way a number of different wrapper files can be generated, thereby avoiding the generation of a single large wrapper file. In this way a number of different wrapper files can be generated, thereby avoiding the generation of a single large wrapper file.
There are a couple of alternative solutions for reducing the size of a wrapper file through the use of command line options. There are a couple of alternative solutions for reducing the size of a wrapper file through the use of command line options.
</p>
<p/>
<b>-fcompact</b><br> <b>-fcompact</b><br>
This command line option will compact the size of the wrapper file without changing the code generated into the wrapper file. This command line option will compact the size of the wrapper file without changing the code generated into the wrapper file.
It simply removes blank lines and joins lines of code together. It simply removes blank lines and joins lines of code together.
This is useful for compilers that have a maximum file size that can be handled. This is useful for compilers that have a maximum file size that can be handled.
<p/> <p>
<b>-fvirtual</b><br> <b>-fvirtual</b><br>
This command line option will remove the generation of superfluous virtual method wrappers. This command line option will remove the generation of superfluous virtual method wrappers.
Consider the following inheritance hierarchy: Consider the following inheritance hierarchy:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -204,7 +218,7 @@ Normally wrappers are generated for both methods, whereas this command line opti
Normal polymorphic behaviour remains as <tt>Derived::method</tt> will still be called should you have Normal polymorphic behaviour remains as <tt>Derived::method</tt> will still be called should you have
a <tt>Derived</tt> instance and call the wrapper for <tt>Base::method</tt>. a <tt>Derived</tt> instance and call the wrapper for <tt>Base::method</tt>.
<p><hr> <hr>
<address>SWIG 1.3 - Last Modified : July 9, 2004</address> <address>SWIG 1.3 - Last Modified : July 9, 2004</address>
</body> </body>

View file

@ -6,47 +6,47 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a> <a name="n1"></a>
<a name="n1"></a><H1>19 SWIG and Ocaml</H1> <H1><a name="Ocaml"></a>21 SWIG and Ocaml</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">Preliminaries</a> <li><a href="#Ocaml_nn2">Preliminaries</a>
<ul> <ul>
<li><a href="#n3">Running SWIG</a> <li><a href="#Ocaml_nn3">Running SWIG</a>
<li><a href="#n4">Compiling the code</a> <li><a href="#Ocaml_nn4">Compiling the code</a>
<li><a href="#n5">The camlp4 module</a> <li><a href="#Ocaml_nn5">The camlp4 module</a>
<li><a href="#n6">Using your module</a> <li><a href="#Ocaml_nn6">Using your module</a>
<li><a href="#n7">Compilation problems and compiling with C++</a> <li><a href="#Ocaml_nn7">Compilation problems and compiling with C++</a>
</ul> </ul>
<li><a href="#n8">The low-level Ocaml/C interface</a> <li><a href="#Ocaml_nn8">The low-level Ocaml/C interface</a>
<ul> <ul>
<li><a href="#n9">The generated module</a> <li><a href="#Ocaml_nn9">The generated module</a>
<li><a href="#n10">Enums</a> <li><a href="#Ocaml_nn10">Enums</a>
<li><a href="#n11">Arrays</a> <li><a href="#Ocaml_nn11">Arrays</a>
<ul> <ul>
<li><a href="#n12">Simple types of bounded arrays</a> <li><a href="#Ocaml_nn12">Simple types of bounded arrays</a>
<li><a href="#n13">Complex and unbounded arrays</a> <li><a href="#Ocaml_nn13">Complex and unbounded arrays</a>
<li><a href="#n14">Using an object</a> <li><a href="#Ocaml_nn14">Using an object</a>
<li><a href="#n15">Example typemap for a function taking float * and int</a> <li><a href="#Ocaml_nn15">Example typemap for a function taking float * and int</a>
</ul> </ul>
<li><a href="#n16">C++ Classes</a> <li><a href="#Ocaml_nn16">C++ Classes</a>
<ul> <ul>
<li><a href="#n17">STL vector and string Example</a> <li><a href="#Ocaml_nn17">STL vector and string Example</a>
<li><a href="#n18">C++ Class Example</a> <li><a href="#Ocaml_nn18">C++ Class Example</a>
<li><a href="#n19">Compiling the example</a> <li><a href="#Ocaml_nn19">Compiling the example</a>
<li><a href="#n20">Sample Session</a> <li><a href="#Ocaml_nn20">Sample Session</a>
</ul> </ul>
<li><a href="#n21">Director Classes</a> <li><a href="#Ocaml_nn21">Director Classes</a>
<ul> <ul>
<li><a href="#n22">Director Introduction</a> <li><a href="#Ocaml_nn22">Director Introduction</a>
<li><a href="#n23">Overriding Methods in Ocaml</a> <li><a href="#Ocaml_nn23">Overriding Methods in Ocaml</a>
<li><a href="#n24">Director Usage Example</a> <li><a href="#Ocaml_nn24">Director Usage Example</a>
<li><a href="#n25">Creating director objects</a> <li><a href="#Ocaml_nn25">Creating director objects</a>
<li><a href="#n26">Typemaps for directors, <tt>directorin, directorout, directorargout</tt></a> <li><a href="#Ocaml_nn26">Typemaps for directors, <tt>directorin, directorout, directorargout</tt></a>
<li><a href="#n27"><tt>directorin</tt> typemap</a> <li><a href="#Ocaml_nn27"><tt>directorin</tt> typemap</a>
<li><a href="#n28"><tt>directorout</tt> typemap</a> <li><a href="#Ocaml_nn28"><tt>directorout</tt> typemap</a>
<li><a href="#n29"><tt>directorargout</tt> typemap</a> <li><a href="#Ocaml_nn29"><tt>directorargout</tt> typemap</a>
</ul> </ul>
<li><a href="#n30">Exceptions</a> <li><a href="#Ocaml_nn30">Exceptions</a>
</ul> </ul>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -73,7 +73,7 @@ If you're not familiar with the Objective Caml language, you can visit
<a href="http://www.ocaml.org/">The Ocaml Website</a>. <a href="http://www.ocaml.org/">The Ocaml Website</a>.
</p> </p>
<a name="n2"></a><H2>19.1 Preliminaries</H2> <H2><a name="Ocaml_nn2"></a>21.1 Preliminaries</H2>
SWIG 1.3 works with Ocaml 3.04 and above. Given the choice, SWIG 1.3 works with Ocaml 3.04 and above. Given the choice,
@ -90,7 +90,7 @@ usual -lxxx against libxxx.so, as well as with Gerd Stolpmann's
file Examples/Makefile illustrate how to compile and link SWIG modules that file Examples/Makefile illustrate how to compile and link SWIG modules that
will be loaded dynamically. This has only been tested on Linux so far. will be loaded dynamically. This has only been tested on Linux so far.
<a name="n3"></a><H3>19.1.1 Running SWIG</H3> <H3><a name="Ocaml_nn3"></a>21.1.1 Running SWIG</H3>
The basics of getting a SWIG Ocaml module up and running The basics of getting a SWIG Ocaml module up and running
@ -99,7 +99,9 @@ will be loaded dynamically. This has only been tested on Linux so far.
option. option.
<blockquote> <blockquote>
<pre>%swig -ocaml example.i</pre> <pre>
%swig -ocaml example.i
</pre>
</blockquote> </blockquote>
<p> This will produce 3 files. The file <tt>example_wrap.c</tt> contains <p> This will produce 3 files. The file <tt>example_wrap.c</tt> contains
@ -109,9 +111,10 @@ you will compile the file <tt>example_wrap.c</tt> with <tt>ocamlc</tt> or
the resulting .ml and .mli files as well, and do the final link with -custom the resulting .ml and .mli files as well, and do the final link with -custom
(not needed for native link). </p> (not needed for native link). </p>
<a name="n4"></a><H3>19.1.2 Compiling the code</H3> <H3><a name="Ocaml_nn4"></a>21.1.2 Compiling the code</H3>
<p>
The O'Caml SWIG module now requires you to compile a module (<tt>Swig</tt>) The O'Caml SWIG module now requires you to compile a module (<tt>Swig</tt>)
separately. In addition to aggregating common SWIG functionality, the Swig separately. In addition to aggregating common SWIG functionality, the Swig
module contains the data structure that represents C/C++ values. This allows module contains the data structure that represents C/C++ values. This allows
@ -122,7 +125,7 @@ the user more freedom with respect to custom typing.
Use <tt>ocamlc</tt> or <tt>ocamlopt</tt> to compile your Use <tt>ocamlc</tt> or <tt>ocamlopt</tt> to compile your
SWIG interface like: SWIG interface like:
<p> </p> </p>
<blockquote> <blockquote>
<pre> <pre>
@ -131,38 +134,47 @@ the user more freedom with respect to custom typing.
% ocamlc -c -ccopt "-I/usr/include/foo" example_wrap.c % ocamlc -c -ccopt "-I/usr/include/foo" example_wrap.c
% ocamlc -c example.mli % ocamlc -c example.mli
% ocamlc -c example.ml % ocamlc -c example.ml
</blockquote> </pre>
</blockquote>
<p> <tt>ocamlc</tt> is aware of .c files and knows how to handle them. Unfortunately, <p> <tt>ocamlc</tt> is aware of .c files and knows how to handle them. Unfortunately,
it does not know about .cxx, .cc, or .cpp files, so when SWIG is invoked it does not know about .cxx, .cc, or .cpp files, so when SWIG is invoked
in C++ mode, you must: </p> in C++ mode, you must: </p>
<blockquote> <blockquote>
<pre>% cp example_wrap.cxx example_wrap.cxx.c<br>% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c<br>% ...<br></pre> <pre>
</blockquote> % cp example_wrap.cxx example_wrap.cxx.c<br>% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c<br>% ...<br>
</pre>
</blockquote>
<a name="n5"></a><H3>19.1.3 The camlp4 module</H3> <H3><a name="Ocaml_nn5"></a>21.1.3 The camlp4 module</H3>
<p>
The camlp4 module (swigp4.ml -&gt; swigp4.cmo) contains a simple rewriter which The camlp4 module (swigp4.ml -&gt; swigp4.cmo) contains a simple rewriter which
makes C++ code blend more seamlessly with objective caml code. It's use is makes C++ code blend more seamlessly with objective caml code. It's use is
optional, but encouraged. The source file is included in the Lib/ocaml optional, but encouraged. The source file is included in the Lib/ocaml
directory of the SWIG source distribution. You can checkout this file with directory of the SWIG source distribution. You can checkout this file with
<tt>"swig -ocaml -co swigp4.ml"</tt>. You should compile the file with <tt>"swig -ocaml -co swigp4.ml"</tt>. You should compile the file with
<tt>"ocamlc -I `camlp4 -where` -pp 'camlp4o pa_extend.cmo q_MLast.cmo' -c swigp4.ml"</tt> <tt>"ocamlc -I `camlp4 -where` -pp 'camlp4o pa_extend.cmo q_MLast.cmo' -c swigp4.ml"</tt>
</p>
<p> <p>
The basic principle of the module is to recognize certain non-caml expressions The basic principle of the module is to recognize certain non-caml expressions
and convert them for use with C++ code as interfaced by SWIG. The camlp4 and convert them for use with C++ code as interfaced by SWIG. The camlp4
module is written to work with generated SWIG interfaces, and probably isn't module is written to work with generated SWIG interfaces, and probably isn't
great to use with anything else. great to use with anything else.
</p>
<p> <p>
Here are the main rewriting rules: Here are the main rewriting rules:
<p> </p>
<table border="1">
<table border="1" summary="Rewriting rules">
<tr><th>Input</th><th>Rewritten to</th></tr> <tr><th>Input</th><th>Rewritten to</th></tr>
<tr><td>f'( ... ) as in<br> atoi'("0") or<br> _exit'(0)</td> <tr><td>f'( ... ) as in<br> atoi'("0") or<br> _exit'(0)</td>
<td>f(C_list [ ... ]) as in<br> atoi (C_list [ C_string "0" ]) or<br> _exit (C_list [ C_int 0 ])</td></tr> <td>f(C_list [ ... ]) as in<br> atoi (C_list [ C_string "0" ]) or<br> _exit (C_list [ C_int 0 ])</td></tr>
<tr><td>object -> method ( ... )</td><td>(invoke object) "method" (C_list [ ... ])</td></tr> <tr><td>object -&gt; method ( ... )</td><td>(invoke object) "method" (C_list [ ... ])</td></tr>
<tr><td> <tr><td>
object <i>'binop</i> argument as in<br> object <i>'binop</i> argument as in<br>
a '+= b</td> a '+= b</td>
@ -178,9 +190,9 @@ and &gt;&gt;, they are replaced by lsl and lsr in operator names.
(invoke a) "!" C_void</td></tr> (invoke a) "!" C_void</td></tr>
<tr><td> <tr><td>
<b>Smart pointer access like this</b><br> <b>Smart pointer access like this</b><br>
object '-> method ( args )<br> object '-&gt; method ( args )<br>
</td><td> </td><td>
(invoke (invoke object "->" C_void)) (invoke (invoke object "-&gt;" C_void))
</td></tr> </td></tr>
<tr><td> <tr><td>
<b>Invoke syntax</b><br> <b>Invoke syntax</b><br>
@ -211,37 +223,47 @@ let b = C_string (getenv "PATH")
</td></tr> </td></tr>
</table> </table>
<a name="n6"></a><H3>19.1.4 Using your module</H3> <H3><a name="Ocaml_nn6"></a>21.1.4 Using your module</H3>
You can test-drive your module by building a <p>
You can test-drive your module by building a
toplevel ocaml interpreter. Consult the ocaml manual for details. toplevel ocaml interpreter. Consult the ocaml manual for details.
</p>
<p>When linking any ocaml bytecode with your module, use the -custom <p>
When linking any ocaml bytecode with your module, use the -custom
option to build your functions into the primitive list. This option to build your functions into the primitive list. This
option is not needed when you build native code. option is not needed when you build native code.
</p>
<a name="n7"></a><H3>19.1.5 Compilation problems and compiling with C++</H3> <H3><a name="Ocaml_nn7"></a>21.1.5 Compilation problems and compiling with C++</H3>
As mentioned above, .cxx files need special <p>
As mentioned above, .cxx files need special
handling to be compiled with <tt>ocamlc</tt>. Other than that, C code handling to be compiled with <tt>ocamlc</tt>. Other than that, C code
that uses <tt>class</tt> as a non-keyword, and C code that is too that uses <tt>class</tt> as a non-keyword, and C code that is too
liberal with pointer types may not compile under the C++ compiler. liberal with pointer types may not compile under the C++ compiler.
Most code meant to be compiled as C++ will not have problems. Most code meant to be compiled as C++ will not have problems.
</p>
<a name="n8"></a><H2>19.2 The low-level Ocaml/C interface</H2> <H2><a name="Ocaml_nn8"></a>21.2 The low-level Ocaml/C interface</H2>
In order to provide access to overloaded functions, and <p>
In order to provide access to overloaded functions, and
provide sensible outputs from them, all C entites are represented as provide sensible outputs from them, all C entites are represented as
members of the c_obj type: members of the c_obj type:
</p>
<p> <p>
In the code as seen by the typemap In the code as seen by the typemap
writer, there is a value, swig_result, that always contains the writer, there is a value, swig_result, that always contains the
current return data. It is a list, and must be appended with the current return data. It is a list, and must be appended with the
caml_list_append function, or with functions and macros provided by caml_list_append function, or with functions and macros provided by
objective caml.<br> objective caml.<br>
</p>
<blockquote><pre> <blockquote><pre>
type c_obj = type c_obj =
@ -284,11 +306,15 @@ appropriate C value and returns a c_obj representing it.</li>
a C_obj, which contains a closure giving method access.</li> a C_obj, which contains a closure giving method access.</li>
</ul> </ul>
Because of this style, a typemap can return any kind of value it
<p>
Because of this style, a typemap can return any kind of value it
wants from a function. &nbsp;This enables out typemaps and inout typemaps wants from a function. &nbsp;This enables out typemaps and inout typemaps
to work well. &nbsp;The one thing to remember about outputting values to work well. &nbsp;The one thing to remember about outputting values
is that you must append them to the return list with swig_result = caml_list_append(swig_result,v).<p> is that you must append them to the return list with swig_result = caml_list_append(swig_result,v).
</p>
<p>
&nbsp;This function will return a new list that has your element &nbsp;This function will return a new list that has your element
appended. Upon return to caml space, the fnhelper function appended. Upon return to caml space, the fnhelper function
beautifies the result. A list containing a single item degrades to beautifies the result. A list containing a single item degrades to
@ -302,13 +328,15 @@ is that you must append them to the return list with swig_result = caml_list_a
allocate memory as caml strings and still use the resulting allocate memory as caml strings and still use the resulting
pointers for C purposes, even using them to construct simple objects pointers for C purposes, even using them to construct simple objects
on. Note, though, that foreign C++ code does not respect the garbage on. Note, though, that foreign C++ code does not respect the garbage
collector, although the SWIG interface does.<p> collector, although the SWIG interface does.</p>
<p>
The wild card type that you can use in lots of different ways is The wild card type that you can use in lots of different ways is
C_obj. It allows you to wrap any type of thing you like as an C_obj. It allows you to wrap any type of thing you like as an
object using the same mechanism that the ocaml module object using the same mechanism that the ocaml module
does. &nbsp;When evaluated in caml_ptr_val, the returned value is does. &nbsp;When evaluated in caml_ptr_val, the returned value is
the result of a call to the object's "&" operator, taken as a pointer. the result of a call to the object's "&amp;" operator, taken as a pointer.
</p>
<p> <p>
You should only construct values using objective caml, or using the You should only construct values using objective caml, or using the
functions caml_val_* functions provided as static functions to a SWIG functions caml_val_* functions provided as static functions to a SWIG
@ -316,20 +344,24 @@ is that you must append them to the return list with swig_result = caml_list_a
provide everything a typemap needs to produce values. In addition, provide everything a typemap needs to produce values. In addition,
value items pass through directly, but you must make your own type value items pass through directly, but you must make your own type
signature for a function that uses value in this way. signature for a function that uses value in this way.
</p>
<a name="n9"></a><H3>19.2.1 The generated module</H3> <H3><a name="Ocaml_nn9"></a>21.2.1 The generated module</H3>
<p>
The SWIG <tt>%module</tt> directive specifies the name of the Ocaml The SWIG <tt>%module</tt> directive specifies the name of the Ocaml
module to be generated. If you specified `<tt>%module example</tt>', module to be generated. If you specified `<tt>%module example</tt>',
then your Ocaml code will be accessible in the module Example. The then your Ocaml code will be accessible in the module Example. The
module name is always capitalized as is the ocaml convention. Note module name is always capitalized as is the ocaml convention. Note
that you must not use any Ocaml keyword to name your module. Remember that you must not use any Ocaml keyword to name your module. Remember
that the keywords are not the same as the C++ ones. <p> that the keywords are not the same as the C++ ones.
</p>
<p>
You can introduce extra code into the output wherever you like with SWIG. You can introduce extra code into the output wherever you like with SWIG.
These are the places you can introduce code: These are the places you can introduce code:
<table border="1"> <table border="1" summary="Extra code sections">
<tr><td>"header"</td><td>This code is inserted near the beginning of the <tr><td>"header"</td><td>This code is inserted near the beginning of the
C wrapper file, before any function definitions.</td></tr> C wrapper file, before any function definitions.</td></tr>
<tr><td>"wrapper"</td><td>This code is inserted in the function definition <tr><td>"wrapper"</td><td>This code is inserted in the function definition
@ -345,11 +377,13 @@ which should run when the module is loaded may be inserted here.
</td></tr> </td></tr>
<tr><td>"classtemplate"</td><td>The "classtemplate" place is special because <tr><td>"classtemplate"</td><td>The "classtemplate" place is special because
it describes the output SWIG will generate for class definitions. it describes the output SWIG will generate for class definitions.
</td></tr>
</table> </table>
<a name="n10"></a><H3>19.2.2 Enums</H3> <H3><a name="Ocaml_nn10"></a>21.2.2 Enums</H3>
<p>
SWIG will wrap enumerations as polymorphic variants in the output SWIG will wrap enumerations as polymorphic variants in the output
Ocaml code, as above in C_enum.&nbsp; In order to support all Ocaml code, as above in C_enum.&nbsp; In order to support all
C++-style uses of enums, the function int_to_enum and enum_to_int are C++-style uses of enums, the function int_to_enum and enum_to_int are
@ -358,7 +392,8 @@ integers. &nbsp;Other than that, correct uses of enums will not have
a problem. &nbsp;Since enum labels may overlap between enums, the a problem. &nbsp;Since enum labels may overlap between enums, the
enum_to_int and int_to_enum functions take an enum type label as an enum_to_int and int_to_enum functions take an enum type label as an
argument. Example: argument. Example:
<p> </p>
<blockquote><pre> <blockquote><pre>
%module enum_test %module enum_test
%{ %{
@ -366,9 +401,11 @@ enum c_enum_type { a = 1, b, c = 4, d = 8 };
%} %}
enum c_enum_type { a = 1, b, c = 4, d = 8 }; enum c_enum_type { a = 1, b, c = 4, d = 8 };
</pre></blockquote> </pre></blockquote>
<p> <p>
The output mli contains: The output mli contains:
<p> </p>
<blockquote><pre> <blockquote><pre>
type c_enum_type = [ type c_enum_type = [
`unknown `unknown
@ -387,7 +424,8 @@ val enum_to_int c_enum_type -&gt; c_obj -&gt; c_obj
</blockquote> </blockquote>
So it's possible to do this: So it's possible to do this:
<blockquote> <blockquote>
<pre>bash-2.05a$ ocamlmktop -custom enum_test_wrap.o enum_test.cmo -o enum_test_top <pre>
bash-2.05a$ ocamlmktop -custom enum_test_wrap.o enum_test.cmo -o enum_test_top
bash-2.05a$ ./enum_test_top bash-2.05a$ ./enum_test_top
Objective Caml version 3.04 Objective Caml version 3.04
@ -401,12 +439,10 @@ val x : Enum_test.c_obj = C_enum `a
</pre> </pre>
</blockquote> </blockquote>
<p> </p> <H3><a name="Ocaml_nn11"></a>21.2.3 Arrays</H3>
<a name="n11"></a><H3>19.2.3 Arrays</H3>
<a name="n12"></a><H4>19.2.3.1 Simple types of bounded arrays</H4> <H4><a name="Ocaml_nn12"></a>21.2.3.1 Simple types of bounded arrays</H4>
<p> <p>
@ -414,6 +450,7 @@ SWIG has support for array types, but you generally will need to provide
a typemap to handle them. You can currently roll your own, or expand a typemap to handle them. You can currently roll your own, or expand
some of the macros provided (but not included by default) with the SWIG some of the macros provided (but not included by default) with the SWIG
distribution. distribution.
</p>
<p> <p>
By including "carray.i", you will get access to some macros that help you By including "carray.i", you will get access to some macros that help you
@ -426,7 +463,7 @@ arrays of simple types with known bounds in your code, but this only works
for arrays whose bounds are completely specified. for arrays whose bounds are completely specified.
</p> </p>
<a name="n13"></a><H4>19.2.3.2 Complex and unbounded arrays</H4> <H4><a name="Ocaml_nn13"></a>21.2.3.2 Complex and unbounded arrays</H4>
<p> <p>
@ -439,7 +476,7 @@ SWIG can't predict which of these methods will be used in the array,
so you have to specify it for yourself in the form of a typemap. so you have to specify it for yourself in the form of a typemap.
</p> </p>
<a name="n14"></a><H4>19.2.3.3 Using an object</H4> <H4><a name="Ocaml_nn14"></a>21.2.3.3 Using an object</H4>
<p> <p>
@ -453,7 +490,7 @@ Consider writing an object when the ending condition of your array is complex,
such as using a required centinel, etc. such as using a required centinel, etc.
</p> </p>
<a name="n15"></a><H4>19.2.3.4 Example typemap for a function taking float * and int</H4> <H4><a name="Ocaml_nn15"></a>21.2.3.4 Example typemap for a function taking float * and int</H4>
<p> <p>
@ -465,11 +502,12 @@ argument is the length of the array passed from ocaml, making passing an array
into this type of function convenient. into this type of function convenient.
</p> </p>
<table border="1" bgcolor="#dddddd"><tr><th><center>tarray.i</center></th></tr> <table border="1" bgcolor="#dddddd" summary="float * and int typemap example">
<tr><th><center>tarray.i</center></th></tr>
<tr><td><pre> <tr><td><pre>
%module tarray %module tarray
%{ %{
#include <stdio.h> #include &lt;stdio.h&gt;
void printfloats( float *tab, int len ) { void printfloats( float *tab, int len ) {
int i; int i;
@ -503,7 +541,7 @@ void printfloats( float *tab, int len );
</pre></td></tr></table> </pre></td></tr></table>
<a name="n16"></a><H3>19.2.4 C++ Classes</H3> <H3><a name="Ocaml_nn16"></a>21.2.4 C++ Classes</H3>
C++ classes, along with structs and unions are represented by C_obj C++ classes, along with structs and unions are represented by C_obj
@ -515,7 +553,8 @@ an object has is represented as a string in the object's method table,
and each method table exists in memory only once. &nbsp;In addition and each method table exists in memory only once. &nbsp;In addition
to any other operators an object might have, certain builtin ones are to any other operators an object might have, certain builtin ones are
provided by SWIG: (all of these take no arguments (C_void)) provided by SWIG: (all of these take no arguments (C_void))
<table>
<table summary="SWIG provided operators">
<tr><td>"~"</td><td>Delete this object</td></tr> <tr><td>"~"</td><td>Delete this object</td></tr>
<tr><td>"&amp;"</td><td>Return an ordinary C_ptr value representing this <tr><td>"&amp;"</td><td>Return an ordinary C_ptr value representing this
object's address</td></tr> object's address</td></tr>
@ -539,9 +578,8 @@ argument. With zero arguments, the value is returned.
Note that this string belongs to the wrapper object, and not Note that this string belongs to the wrapper object, and not
the underlying pointer, so using create_[x]_from_ptr alters the the underlying pointer, so using create_[x]_from_ptr alters the
returned value for the same object. returned value for the same object.
<p>
<a name="n17"></a><H4>19.2.4.1 STL vector and string Example</H4> <H4><a name="Ocaml_nn17"></a>21.2.4.1 STL vector and string Example</H4>
Standard typemaps are now provided for STL vector and string. More are in Standard typemaps are now provided for STL vector and string. More are in
@ -550,7 +588,8 @@ as strings. STL string references don't mutate the original string, (which
might be surprising), because Ocaml strings are mutable but have fixed might be surprising), because Ocaml strings are mutable but have fixed
length. Instead, use multiple returns, as in the argout_ref example. length. Instead, use multiple returns, as in the argout_ref example.
<table border="1" bgcolor="#dddddd"><tr><th><center>example.i</center></th></tr> <table border="1" bgcolor="#dddddd" summary="STL vector and string example">
<tr><th><center>example.i</center></th></tr>
<tr><td><pre> <tr><td><pre>
%module example %module example
%{ %{
@ -567,12 +606,17 @@ namespace std {
</pre></td></tr> </pre></td></tr>
<tr><td><font size="-1"><i>This example is in Examples/ocaml/stl <tr><td><font size="-1"><i>This example is in Examples/ocaml/stl
</i></font></td></tr> </i></font></td></tr>
</table><p> </table>
Since there's a makefile in that directory, the example is easy to build.<p> <p>
Since there's a makefile in that directory, the example is easy to build.
</p>
<p>
Here's a sample transcript of an interactive session using a string vector Here's a sample transcript of an interactive session using a string vector
after making a toplevel (make toplevel). This example uses the camlp4 after making a toplevel (make toplevel). This example uses the camlp4
module. module.
</p>
<blockquote><pre> <blockquote><pre>
bash-2.05a$ ./example_top bash-2.05a$ ./example_top
@ -583,27 +627,27 @@ bash-2.05a$ ./example_top
# open Swig ;; # open Swig ;;
# open Example ;; # open Example ;;
# let x = new_StringVector '() ;; # let x = new_StringVector '() ;;
val x : Example.c_obj = C_obj <fun> val x : Example.c_obj = C_obj &lt;fun&gt;
# x -> ":methods" () ;; # x -&gt; ":methods" () ;;
- : Example.c_obj = - : Example.c_obj =
C_list C_list
[C_string "nop"; C_string "size"; C_string "empty"; C_string "clear"; [C_string "nop"; C_string "size"; C_string "empty"; C_string "clear";
C_string "push_back"; C_string "[]"; C_string "="; C_string "set"; C_string "push_back"; C_string "[]"; C_string "="; C_string "set";
C_string "~"; C_string "&"; C_string ":parents"; C_string ":classof"; C_string "~"; C_string "&amp;"; C_string ":parents"; C_string ":classof";
C_string ":methods"] C_string ":methods"]
# x -> push_back ("foo") ;; # x -&gt; push_back ("foo") ;;
- : Example.c_obj = C_void - : Example.c_obj = C_void
# x -> push_back ("bar") ;; # x -&gt; push_back ("bar") ;;
- : Example.c_obj = C_void - : Example.c_obj = C_void
# x -> push_back ("baz") ;; # x -&gt; push_back ("baz") ;;
- : Example.c_obj = C_void - : Example.c_obj = C_void
# x '[1] ;; # x '[1] ;;
- : Example.c_obj = C_string "bar" - : Example.c_obj = C_string "bar"
# x -> set (1,"spam") ;; # x -&gt; set (1,"spam") ;;
- : Example.c_obj = C_void - : Example.c_obj = C_void
# x '[1] ;; # x '[1] ;;
- : Example.c_obj = C_string "spam" - : Example.c_obj = C_string "spam"
# for i = 0 to (x -> size() as int) - 1 do # for i = 0 to (x -&gt; size() as int) - 1 do
print_endline ((x '[i to int]) as string) print_endline ((x '[i to int]) as string)
done ;; done ;;
foo foo
@ -613,12 +657,13 @@ baz
# #
</pre></blockquote> </pre></blockquote>
<a name="n18"></a><H4>19.2.4.2 C++ Class Example</H4> <H4><a name="Ocaml_nn18"></a>21.2.4.2 C++ Class Example</H4>
Here's a simple example using Trolltech's Qt Library: Here's a simple example using Trolltech's Qt Library:
<table border="1" bgcolor="#dddddd"><tr><th><center>qt.i</center></th></tr> <table border="1" bgcolor="#dddddd" summary="Qt Library example">
<tr><th><center>qt.i</center></th></tr>
<tr><td><pre> <tr><td><pre>
%module qt %module qt
%{ %{
@ -638,9 +683,9 @@ public:
void resize( int x, int y ); void resize( int x, int y );
void show(); void show();
}; };
</pre></td></tr></table><p> </pre></td></tr></table>
<a name="n19"></a><H4>19.2.4.3 Compiling the example</H4> <H4><a name="Ocaml_nn19"></a>21.2.4.3 Compiling the example</H4>
<blockquote><pre> <blockquote><pre>
@ -658,7 +703,7 @@ bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
-L$QTPATH/lib -cclib -lqt -L$QTPATH/lib -cclib -lqt
</pre></blockquote> </pre></blockquote>
<a name="n20"></a><H4>19.2.4.4 Sample Session</H4> <H4><a name="Ocaml_nn20"></a>21.2.4.4 Sample Session</H4>
<blockquote><pre> <blockquote><pre>
@ -670,33 +715,40 @@ bash-2.05a$ ./qt_top
# open Swig ;; # open Swig ;;
# open Qt ;; # open Qt ;;
# let a = new_QApplication '(0,0) ;; # let a = new_QApplication '(0,0) ;;
val a : Qt.c_obj = C_obj <fun> val a : Qt.c_obj = C_obj &lt;fun&gt;
# let hello = new_QPushButton '("hi",0) ;; # let hello = new_QPushButton '("hi",0) ;;
val hello : Qt.c_obj = C_obj <fun> val hello : Qt.c_obj = C_obj &lt;fun&gt;
# hello -> resize (100,30) ;; # hello -&gt; resize (100,30) ;;
- : Qt.c_obj = C_void - : Qt.c_obj = C_void
# hello -> show () ;; # hello -&gt; show () ;;
- : Qt.c_obj = C_void - : Qt.c_obj = C_void
# a -> exec () ;; # a -&gt; exec () ;;
</pre></blockquote><p> </pre></blockquote>
<p>
Assuming you have a working installation of QT, you will see a window Assuming you have a working installation of QT, you will see a window
containing the string "hi" in a button. containing the string "hi" in a button.
</p>
<a name="n21"></a><H3>19.2.5 Director Classes</H3> <H3><a name="Ocaml_nn21"></a>21.2.5 Director Classes</H3>
<a name="n22"></a><H4>19.2.5.1 Director Introduction</H4> <H4><a name="Ocaml_nn22"></a>21.2.5.1 Director Introduction</H4>
<p>
Director classes are classes which allow Ocaml code to override the public Director classes are classes which allow Ocaml code to override the public
methods of a C++ object. This facility allows the user to use C++ libraries methods of a C++ object. This facility allows the user to use C++ libraries
that require a derived class to provide application specific functionality in that require a derived class to provide application specific functionality in
the context of an application or utility framework. the context of an application or utility framework.
</p>
<p> <p>
You can turn on director classes by using an optional module argument like You can turn on director classes by using an optional module argument like
this: this:
<pre><blockquote><p> </p>
<blockquote><pre>
%module(directors="1") %module(directors="1")
... ...
@ -706,9 +758,9 @@ this:
class foo { class foo {
... ...
}; };
</p></blockquote></pre> </pre></blockquote>
<a name="n23"></a><H4>19.2.5.2 Overriding Methods in Ocaml</H4> <H4><a name="Ocaml_nn23"></a>21.2.5.2 Overriding Methods in Ocaml</H4>
<p> <p>
@ -721,21 +773,26 @@ underlying implemenation. The object you receive is the underlying object,
so you are free to call any methods you want from within your derived method. so you are free to call any methods you want from within your derived method.
Note that calls to the underlying object do not invoke Ocaml code. You need Note that calls to the underlying object do not invoke Ocaml code. You need
to handle that yourself. to handle that yourself.
</p>
<p> <p>
<tt>new_derived_object</tt> receives your function, the function that creates <tt>new_derived_object</tt> receives your function, the function that creates
the underlying object, and any constructor arguments, and provides an the underlying object, and any constructor arguments, and provides an
object that you can use in any usual way. When C++ code calls one of the object that you can use in any usual way. When C++ code calls one of the
object's methods, the object invokes the Ocaml function as if it had been object's methods, the object invokes the Ocaml function as if it had been
invoked from Ocaml, allowing any method definitions to override the C++ ones. invoked from Ocaml, allowing any method definitions to override the C++ ones.
</p>
<p> <p>
In this example, I'll examine the objective caml code involved in providing In this example, I'll examine the objective caml code involved in providing
an overloaded class. This example is contained in Examples/ocaml/shapes. an overloaded class. This example is contained in Examples/ocaml/shapes.
<p> </p>
<a name="n24"></a><H4>19.2.5.3 Director Usage Example</H4> <H4><a name="Ocaml_nn24"></a>21.2.5.3 Director Usage Example</H4>
<table border="1" bgcolor="#dddddd"><tr><th><center>example_prog.ml</center> <table border="1" bgcolor="#dddddd" summary="Director usage example">
<tr><th><center>example_prog.ml</center>
</th></tr> </th></tr>
<tr><td><pre> <tr><td><pre>
open Swig open Swig
@ -745,14 +802,14 @@ open Example
let triangle_class pts ob meth args = let triangle_class pts ob meth args =
match meth with match meth with
"cover" -> "cover" -&gt;
(match args with (match args with
C_list [ x_arg ; y_arg ] -> C_list [ x_arg ; y_arg ] -&gt;
let xa = x_arg as float let xa = x_arg as float
and ya = y_arg as float in and ya = y_arg as float in
(point_in_triangle pts xa ya) to bool (point_in_triangle pts xa ya) to bool
| _ -> raise (Failure "cover needs two double arguments.")) | _ -&gt; raise (Failure "cover needs two double arguments."))
| _ -> (invoke ob) meth args ;; | _ -&gt; (invoke ob) meth args ;;
let triangle = let triangle =
new_derived_object new_derived_object
@ -763,6 +820,7 @@ let triangle =
let _ = _draw_shape_coverage '(triangle, C_int 60, C_int 20) ;; let _ = _draw_shape_coverage '(triangle, C_int 60, C_int 20) ;;
</pre></td></tr> </pre></td></tr>
</table> </table>
<p> <p>
This is the meat of what you need to do. The actual "class" definition This is the meat of what you need to do. The actual "class" definition
containing the overloaded method is defined in the function triangle_class. containing the overloaded method is defined in the function triangle_class.
@ -776,27 +834,31 @@ generally be Failure, or NotObject. You must call other ocaml methods that
you rely on yourself. Due to the way directors are implemented, method you rely on yourself. Due to the way directors are implemented, method
calls on your object from with ocaml code will always invoke C++ methods calls on your object from with ocaml code will always invoke C++ methods
even if they are overridden in ocaml. even if they are overridden in ocaml.
</p>
<p> <p>
In the example, the draw_shape_coverage function plots the indicated number In the example, the draw_shape_coverage function plots the indicated number
of points as either covered (<tt>x</tt>) or uncovered (<tt> </tt>) between of points as either covered (<tt>x</tt>) or uncovered ( ) between
0 and 1 on the X and Y axes. Your shape implementation can provide any 0 and 1 on the X and Y axes. Your shape implementation can provide any
coverage map it likes, as long as it responds to the "cover" method call coverage map it likes, as long as it responds to the "cover" method call
with a boolean return (the underlying method returns bool). This might allow with a boolean return (the underlying method returns bool). This might allow
a tricky shape implementation, such as a boolean combination, to be expressed a tricky shape implementation, such as a boolean combination, to be expressed
in a more effortless style in ocaml, while leaving the "engine" part of the in a more effortless style in ocaml, while leaving the "engine" part of the
program in C++. program in C++.
<p> </p>
<a name="n25"></a><H4>19.2.5.4 Creating director objects</H4>
<H4><a name="Ocaml_nn25"></a>21.2.5.4 Creating director objects</H4>
The definition of the actual object triangle can be described this way: The definition of the actual object triangle can be described this way:
<pre><blockquote><p> <blockquote><pre>
let triangle = let triangle =
new_derived_object new_derived_object
new_shape new_shape
(triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0))) (triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
'() '()
</p></blockquote></pre> </pre></blockquote>
<p> <p>
The first argument to <tt>new_derived_object</tt>, new_shape is the method The first argument to <tt>new_derived_object</tt>, new_shape is the method
which returns a shape instance. This function will be invoked with the which returns a shape instance. This function will be invoked with the
@ -806,6 +868,8 @@ The augmented constructor for a director class needs the first argument
to determine whether it is being constructed as a derived object, or as to determine whether it is being constructed as a derived object, or as
an object of the indicated type only (in this case <tt>shape</tt>). The an object of the indicated type only (in this case <tt>shape</tt>). The
Second argument is a closure that will be added to the final C_obj. Second argument is a closure that will be added to the final C_obj.
</p>
<p> <p>
The actual object passed to the self parameter of the director object will The actual object passed to the self parameter of the director object will
be a C_director_core, containing a c_obj option ref and a c_obj. The be a C_director_core, containing a c_obj option ref and a c_obj. The
@ -819,8 +883,9 @@ after that point (the actual raise is from an inner function used by
new_derived_object, and throws NotObject). This prevents a deleted C++ new_derived_object, and throws NotObject). This prevents a deleted C++
object from causing a core dump, as long as the object is destroyed object from causing a core dump, as long as the object is destroyed
properly. properly.
</p>
<a name="n26"></a><H4>19.2.5.5 Typemaps for directors, <tt>directorin, directorout, directorargout</tt></H4> <H4><a name="Ocaml_nn26"></a>21.2.5.5 Typemaps for directors, <tt>directorin, directorout, directorargout</tt></H4>
<p> <p>
@ -829,8 +894,9 @@ are used in place of <tt>in, out, argout</tt> typemaps, except that their
direction is reversed. They provide for you to provide argout values, as direction is reversed. They provide for you to provide argout values, as
well as a function return value in the same way you provide function arguments, well as a function return value in the same way you provide function arguments,
and to receive arguments the same way you normally receive function returns. and to receive arguments the same way you normally receive function returns.
</P> </p>
<a name="n27"></a><H4>19.2.5.6 <tt>directorin</tt> typemap</H4>
<H4><a name="Ocaml_nn27"></a>21.2.5.6 <tt>directorin</tt> typemap</H4>
<p> <p>
@ -841,7 +907,7 @@ code receives when you are called. In general, a simple <tt>directorin</tt> typ
can use the same body as a simple <tt>out</tt> typemap. can use the same body as a simple <tt>out</tt> typemap.
</p> </p>
<a name="n28"></a><H4>19.2.5.7 <tt>directorout</tt> typemap</H4> <H4><a name="Ocaml_nn28"></a>21.2.5.7 <tt>directorout</tt> typemap</H4>
<p> <p>
@ -852,11 +918,11 @@ for the same type, except when there are special requirements for object
ownership, etc. ownership, etc.
</p> </p>
<a name="n29"></a><H4>19.2.5.8 <tt>directorargout</tt> typemap</H4> <H4><a name="Ocaml_nn29"></a>21.2.5.8 <tt>directorargout</tt> typemap</H4>
<p> <p>
C++ allows function arguments which are by pointer (*) and by reference (&) C++ allows function arguments which are by pointer (*) and by reference (&amp;)
to receive a value from the called function, as well as sending one there. to receive a value from the called function, as well as sending one there.
Sometimes, this is the main purpose of the argument given. <tt>directorargout</tt> Sometimes, this is the main purpose of the argument given. <tt>directorargout</tt>
typemaps allow your caml code to emulate this by specifying additional return typemaps allow your caml code to emulate this by specifying additional return
@ -869,7 +935,7 @@ In the event that you don't specify all of the necessary values, integral
values will read zero, and struct or object returns have undefined results. values will read zero, and struct or object returns have undefined results.
</p> </p>
<a name="n30"></a><H3>19.2.6 Exceptions</H3> <H3><a name="Ocaml_nn30"></a>21.2.6 Exceptions</H3>
Catching exceptions is now supported using SWIG's %exception feature. A simple Catching exceptions is now supported using SWIG's %exception feature. A simple

File diff suppressed because it is too large Load diff

View file

@ -6,44 +6,50 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>21 SWIG and PHP4</H1> <H1><a name="Php"></a>23 SWIG and PHP4</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">Preliminaries</a> <li><a href="#Php_nn2">Preliminaries</a>
<li><a href="#n3">Building PHP4 Extensions</a> <li><a href="#Php_nn3">Building PHP4 Extensions</a>
<ul> <ul>
<li><a href="#n4">Building a loadable extension</a> <li><a href="#Php_nn4">Building a loadable extension</a>
<li><a href="#n5">Basic PHP4 interface</a> <li><a href="#Php_nn5">Basic PHP4 interface</a>
<li><a href="#n6">Functions</a> <li><a href="#Php_nn6">Functions</a>
<li><a href="#n7">Global Variables</a> <li><a href="#Php_nn7">Global Variables</a>
<li><a href="#n8">Pointers </a> <li><a href="#Php_nn8">Pointers </a>
<li><a href="#n9">Structures and C++ classes</a> <li><a href="#Php_nn9">Structures and C++ classes</a>
<li><a href="#n10">Constants</a> <li><a href="#Php_nn10">Constants</a>
<li><a href="#n11">Shadow classes</a> <li><a href="#Php_nn11">Shadow classes</a>
<li><a href="#n12">Constructors and Destructers</a> <li><a href="#Php_nn12">Constructors and Destructers</a>
<li><a href="#n13">Static Member Variables</a> <li><a href="#Php_nn13">Static Member Variables</a>
<li><a href="#n14">PHP4 Pragmas</a> <li><a href="#Php_nn14">PHP4 Pragmas</a>
<li><a href="#n15">Building extensions into php</a> <li><a href="#Php_nn15">Building extensions into php</a>
<li><a href="#n16">To be furthered...</a> <li><a href="#Php_nn16">To be furthered...</a>
</ul> </ul>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
<p>
<b>Caution: This chapter (and module!) is still under construction</b> <b>Caution: This chapter (and module!) is still under construction</b>
</p>
<p>
In this chapter, we discuss SWIG's support of PHP4. The PHP4 module is In this chapter, we discuss SWIG's support of PHP4. The PHP4 module is
still under development so some of the features below may not work properly still under development so some of the features below may not work properly
(or at all!.) (or at all!.)
</p>
<p> <p>
The PHP4 module has undergone a lot of changes recently affecting the The PHP4 module has undergone a lot of changes recently affecting the
way shadow classes are implemented so you should read this document even way shadow classes are implemented so you should read this document even
if you thought you were familiar with what it said. The major change is if you thought you were familiar with what it said. The major change is
that shadow classes are implemented inside the php module in C++ instead that shadow classes are implemented inside the php module in C++ instead
of in the generated .php file in php. of in the generated .php file in php.
</p>
<a name="n2"></a><H2>21.1 Preliminaries</H2> <H2><a name="Php_nn2"></a>23.1 Preliminaries</H2>
In order to use this module, you will need to have a copy of the PHP 4.0 (or In order to use this module, you will need to have a copy of the PHP 4.0 (or
@ -53,15 +59,18 @@ need either the php binary or the Apache php module. If you want to build your
extension into php directly (without having the overhead of loading it into extension into php directly (without having the overhead of loading it into
each script), you will need the complete PHP source tree available. each script), you will need the complete PHP source tree available.
<a name="n3"></a><H2>21.2 Building PHP4 Extensions</H2> <H2><a name="Php_nn3"></a>23.2 Building PHP4 Extensions</H2>
To build a PHP4 extension, run swig using the <tt>-php4</tt> option as follows :
<p> <p>
To build a PHP4 extension, run swig using the <tt>-php4</tt> option as follows :
</p>
<blockquote><pre> <blockquote><pre>
swig -php4 example.i swig -php4 example.i
</pre></blockquote> </pre></blockquote>
<p>
This will produce 3 files by default. The first file, <tt>example_wrap.c</tt> This will produce 3 files by default. The first file, <tt>example_wrap.c</tt>
contains all of the C code needed to build a PHP4 extension. The second file, contains all of the C code needed to build a PHP4 extension. The second file,
<tt>php_example.h</tt> contains the header information needed to link the <tt>php_example.h</tt> contains the header information needed to link the
@ -71,6 +80,8 @@ a place-holder for extra code specified in the interface file. If you want to
build your extension using the <tt>phpize</tt> utility, or if you want to build your extension using the <tt>phpize</tt> utility, or if you want to
build your module into PHP directly, you can specify the <tt>-phpfull</tt> build your module into PHP directly, you can specify the <tt>-phpfull</tt>
command line argument to swig. command line argument to swig.
</p>
<p> <p>
The <tt>-phpfull</tt> will generate three extra files. The <tt>-phpfull</tt> will generate three extra files.
The first extra file, <tt>config.m4</tt> contains the shell code needed to The first extra file, <tt>config.m4</tt> contains the shell code needed to
@ -78,6 +89,8 @@ enable the extension as part of the PHP4 build process. The second extra file,
<tt>Makefile.in</tt> contains the information needed to build the final <tt>Makefile.in</tt> contains the information needed to build the final
Makefile after substitutions. The third and final extra file, <tt>CREDITS</tt> Makefile after substitutions. The third and final extra file, <tt>CREDITS</tt>
should contain the credits for the extension. should contain the credits for the extension.
</p>
<p> <p>
To finish building the extension, you have two choices. You can either build To finish building the extension, you have two choices. You can either build
the extension as a seperate object file which will then have to be explicitly the extension as a seperate object file which will then have to be explicitly
@ -85,19 +98,25 @@ loaded by each script. Or you can rebuild the entire php source tree and build
the extension into the php executable/library so it will be available in every the extension into the php executable/library so it will be available in every
script. The first choice is the default, however it can be changed by passing script. The first choice is the default, however it can be changed by passing
the '-phpfull' command line switch to select the second build method. the '-phpfull' command line switch to select the second build method.
</p>
<a name="n4"></a><H3>21.2.1 Building a loadable extension</H3> <H3><a name="Php_nn4"></a>23.2.1 Building a loadable extension</H3>
<p>
To build a dynamic module for PHP, you have two options. You can use the To build a dynamic module for PHP, you have two options. You can use the
<tt>phpize</tt> utility, or you can do it manually. <tt>phpize</tt> utility, or you can do it manually.
</p>
<p> <p>
To build manually, use a compile string similar to this (different for each To build manually, use a compile string similar to this (different for each
OS): OS):
</p>
<blockquote><pre> <blockquote><pre>
cc -I.. $(PHPINC) -fpic -c example_wrap.c cc -I.. $(PHPINC) -fpic -c example_wrap.c
cc -shared example_wrap.o -o libexample.so cc -shared example_wrap.o -o libexample.so
</pre></blockquote> </pre></blockquote>
<p> <p>
To build with phpize, after you have run swig you will need To build with phpize, after you have run swig you will need
to run the 'phpize' command (installed as part of php) in the same to run the 'phpize' command (installed as part of php) in the same
@ -111,12 +130,17 @@ to check that a correct library version is installed or correct header files
are included, etc, but you must edit this file before running phpize. ) are included, etc, but you must edit this file before running phpize. )
If you like SWIG can generate simple extra tests for libraries and header If you like SWIG can generate simple extra tests for libraries and header
files for you. files for you.
</p>
<blockquote><pre> <blockquote><pre>
swig -php4 -phpfull -withlibs "xapian omquery" --withincs "om.h" swig -php4 -phpfull -withlibs "xapian omquery" --withincs "om.h"
</pre></blockquote> </pre></blockquote>
<p> <p>
Will include in the config.m4 search for libxapian.a or libxapian.so and Will include in the config.m4 search for libxapian.a or libxapian.so and
search for libomquery.a or libomquery.so as well as a search for om.h search for libomquery.a or libomquery.so as well as a search for om.h
</p>
<p> <p>
If you depend on source files not generated by SWIG, before generated If you depend on source files not generated by SWIG, before generated
configure file, you may need to edit the <tt> configure file, you may need to edit the <tt>
@ -125,15 +149,21 @@ Makefile.in</tt> file. This contains the names of the source files to compile
linked in. If there are extra C files to compile, you will need to add them linked in. If there are extra C files to compile, you will need to add them
to the Makefile.in, or add the names of libraries if they are needed. In to the Makefile.in, or add the names of libraries if they are needed. In
simple cases SWIG is pretty good at generating a complete Makefile.in and simple cases SWIG is pretty good at generating a complete Makefile.in and
config.m4 which need no further editing. <p> config.m4 which need no further editing.
</p>
<p>
You then run the configure script with the command line argument needed You then run the configure script with the command line argument needed
to enable the extension. Then run make, which builds the extension. to enable the extension. Then run make, which builds the extension.
The extension object file will be left in the modules sub directory, you can The extension object file will be left in the modules sub directory, you can
move it to wherever it is convenient to call from your php script. move it to wherever it is convenient to call from your php script.
<p> </p>
<p> <p>
To test the extension from a PHP script, you need to load it first. You do To test the extension from a PHP script, you need to load it first. You do
this by putting the line, this by putting the line,
</p>
<blockquote><pre> <blockquote><pre>
dl("/path/to/modulename.so"); // Load the module dl("/path/to/modulename.so"); // Load the module
</pre></blockquote> </pre></blockquote>
@ -146,23 +176,28 @@ attempts to do the <tt>dl()</tt> call for you:
A more complicated method which builds the module directly into the <tt>php</tt> A more complicated method which builds the module directly into the <tt>php</tt>
executable is described <a href="n12">below</a>. executable is described <a href="n12">below</a>.
<a name="n5"></a><H3>21.2.2 Basic PHP4 interface</H3> <H3><a name="Php_nn5"></a>23.2.2 Basic PHP4 interface</H3>
<a name="n6"></a><H3>21.2.3 Functions</H3> <H3><a name="Php_nn6"></a>23.2.3 Functions</H3>
C functions are converted into PHP functions. Default/optional arguments are
also allowed. An interface file like this :<p>
<p> <p>
<blockquote><pre>%module default C functions are converted into PHP functions. Default/optional arguments are
also allowed. An interface file like this :
</p>
<blockquote><pre>
%module default
int foo(int a); int foo(int a);
double bar(double, double b = 3.0); double bar(double, double b = 3.0);
... ...
</pre></blockquote> </pre></blockquote>
Will be accessed in PHP like this :<p>
<p> <p>
Will be accessed in PHP like this :
</p>
<blockquote><pre> <blockquote><pre>
dl("default.so"); $a = foo(2); dl("default.so"); $a = foo(2);
$b = bar(3.5, -1.5); $b = bar(3.5, -1.5);
@ -170,50 +205,65 @@ $c = bar(3.5); # Use default argument for 2nd parameter
</pre></blockquote> </pre></blockquote>
<a name="n7"></a><H3>21.2.4 Global Variables</H3> <H3><a name="Php_nn7"></a>23.2.4 Global Variables</H3>
<p>
Global variables are difficult for PHP to handle, unlike Perl, their is no Global variables are difficult for PHP to handle, unlike Perl, their is no
'magic' way to intercept modifications made to variables, so changes in a PHP 'magic' way to intercept modifications made to variables, so changes in a PHP
variable will not be reflected in its C equivalent. To get around the problem, variable will not be reflected in its C equivalent. To get around the problem,
two extra function are generated, <tt>Swig_sync_c()</tt> and <tt>Swig_sync_php()</tt>. These functions are called at the start and end of every function call, two extra function are generated, <tt>Swig_sync_c()</tt> and <tt>Swig_sync_php()</tt>. These functions are called at the start and end of every function call,
ensuring changes made in PHP are updated in C ( and vice versa. ) Because this ensuring changes made in PHP are updated in C ( and vice versa. ) Because this
is handled for you, you can modify the variables in PHP as normal, e.g. is handled for you, you can modify the variables in PHP as normal, e.g.
<p><p> </p>
<blockquote><pre>%module example;
<blockquote><pre>
%module example;
... ...
double seki = 2; double seki = 2;
... ...
int example_func(void); int example_func(void);
</pre></blockquote> </pre></blockquote>
is accessed as follow :<p>
<p> <p>
is accessed as follow :
</p>
<blockquote><pre> <blockquote><pre>
dl("example.so"); dl("example.so");
print $seki; print $seki;
$seki = $seki * 2; # Does not affect C variable, still equal to 2 $seki = $seki * 2; # Does not affect C variable, still equal to 2
example_func(); # Syncs C variable to PHP Variable, now both 4 example_func(); # Syncs C variable to PHP Variable, now both 4
</pre></blockquote> </pre></blockquote>
<p>
SWIG supports global variables of all C datatypes including pointers and complex SWIG supports global variables of all C datatypes including pointers and complex
objects.<p> objects.
</p>
<a name="n8"></a><H3>21.2.5 Pointers </H3> <H3><a name="Php_nn8"></a>23.2.5 Pointers </H3>
<p>
Pointers to C/C++ objects <b>no longer</b> represented as character Pointers to C/C++ objects <b>no longer</b> represented as character
strings such as:<tt>_523d3f4_Circle_p</tt>, instead they are represented strings such as:<tt>_523d3f4_Circle_p</tt>, instead they are represented
as PHP resources, rather like MySQL connection handles. as PHP resources, rather like MySQL connection handles.
</p>
<p> <p>
You can also explicitly create a NULL pointer as a string "NULL" You can also explicitly create a NULL pointer as a string "NULL"
or by passing a null or empty value. or by passing a null or empty value.
</p>
<a name="n9"></a><H3>21.2.6 Structures and C++ classes</H3> <H3><a name="Php_nn9"></a>23.2.6 Structures and C++ classes</H3>
For structures and classes, SWIG produces accessor fuction for each member function and data. For example :<p>
<p> <p>
<blockquote><pre>%module vector For structures and classes, SWIG produces accessor fuction for each member function and data. For example :
</p>
<blockquote><pre>
%module vector
class Vector { class Vector {
public: public:
@ -224,7 +274,11 @@ public:
}; };
</pre></blockquote> </pre></blockquote>
This gets turned into the following collection of PHP functions :<p>
<p>
This gets turned into the following collection of PHP functions :
</p>
<blockquote><pre> <blockquote><pre>
Vector_x_set($obj); Vector_x_set($obj);
Vector_x_get($obj); Vector_x_get($obj);
@ -241,25 +295,29 @@ To use the class, simply use these functions. However, SWIG also has a mechanism
for creating shadow classes that hides these functions and uses an object for creating shadow classes that hides these functions and uses an object
oriented interface instead - see <a href="n7">below</a> oriented interface instead - see <a href="n7">below</a>
<a name="n10"></a><H3>21.2.7 Constants</H3> <H3><a name="Php_nn10"></a>23.2.7 Constants</H3>
<p>
These work in much the same way as in C/C++, constants can be defined by using These work in much the same way as in C/C++, constants can be defined by using
either the normal C pre-processor declarations, or the <tt>%constant</tt> SWIG either the normal C pre-processor declarations, or the <tt>%constant</tt> SWIG
directive. These will then be available from your PHP script as a PHP constant, directive. These will then be available from your PHP script as a PHP constant,
(e.g. no dollar sign is needed to access them. ) For example, with a swig file like this, (e.g. no dollar sign is needed to access them. ) For example, with a swig file like this,
<p> </p>
<blockquote><pre> <blockquote><pre>
%module example %module example
#define PI 3.14159 #define PI 3.14159
%constant int E = 2.71828 %constant int E = 2.71828
</pre> </pre>
</blockquote> </blockquote>
<p> <p>
you can access from in your php script like this, you can access from in your php script like this,
</p>
<blockquote><pre> <blockquote><pre>
dl("libexample.so"); dl("libexample.so");
@ -274,16 +332,19 @@ echo "E = " . E . "\n";
There are two peculiarities with using constants in PHP4. The first is that There are two peculiarities with using constants in PHP4. The first is that
if you try to use an undeclared constant, it will evaulate to a string if you try to use an undeclared constant, it will evaulate to a string
set to the constants name. For example, set to the constants name. For example,
<p> </p>
<blockquote><pre> <blockquote><pre>
%module example %module example
#define EASY_TO_MISPELL 0 #define EASY_TO_MISPELL 0
</pre> </pre>
</blockquote> </blockquote>
accessed incorrectly in PHP,
<p> <p>
accessed incorrectly in PHP,
</p>
<blockquote> <blockquote>
<pre> <pre>
dl("libexample.so"); dl("libexample.so");
@ -296,93 +357,120 @@ if(EASY_TO_MISPEL) {
</pre> </pre>
</blockquote> </blockquote>
<p>
<p>
will issue a warning about the undeclared constant, but will then evalute will issue a warning about the undeclared constant, but will then evalute
it and turn it into a string ('EASY_TO_MISPEL'), which evaluates to true, it and turn it into a string ('EASY_TO_MISPEL'), which evaluates to true,
rather than the value of the constant which would be false. This is a feature. rather than the value of the constant which would be false. This is a feature.
</p>
<p> <p>
The second 'feature' is that although constants are case sensitive (by default), The second 'feature' is that although constants are case sensitive (by default),
you cannot declare a constant twice with alternative cases. E.g., you cannot declare a constant twice with alternative cases. E.g.,
<p> </p>
<blockquote> <blockquote>
<pre> <pre>
%module example %module example
#define TEST Hello #define TEST Hello
#define Test World #define Test World
</pre> </pre>
</blockquote> </blockquote>
accessed from PHP,
<p> <p>
<pre> accessed from PHP,
</p>
<blockquote> <blockquote>
<pre>
dl("libexample.so"); dl("libexample.so");
echo TEST, Test; echo TEST, Test;
</blockquote>
</pre> </pre>
</blockquote>
<p> <p>
will output "Hello Test" rather than "Hello World". This is because internally, will output "Hello Test" rather than "Hello World". This is because internally,
all constants are stored in a hash table by their lower case name, so 'TEST' and all constants are stored in a hash table by their lower case name, so 'TEST' and
'Test' will map to the same hash element ('Test'). But, because we declared them case sensitive, the Zend engine will test if the case matches with the case the 'Test' will map to the same hash element ('Test'). But, because we declared them case sensitive, the Zend engine will test if the case matches with the case the
constant was declared with first. constant was declared with first.
</p>
<p> <p>
So, in the example above, the TEST constant was declared first, and will be stored under the hash element 'test'. The 'Test' constant will also map to the same hash element 'test', but will not overwrite it. When called from the script, the TEST constant will again be mapped to the hash element 'test' so the constant will be retrieved. The case will then be checked, and will match up, so the value ('Hello') will be returned. When 'Test' is evaulated, it will also map to the same hash element 'test'. The same constant will be retrieved, this time though the case check will fail as 'Test' != 'TEST'. So PHP will assume that Test is a undeclared constant, and as explained above, will return it as a string set to the constant name ('Test'). Hence the script above will print 'Hello Test'. If So, in the example above, the TEST constant was declared first, and will be stored under the hash element 'test'. The 'Test' constant will also map to the same hash element 'test', but will not overwrite it. When called from the script, the TEST constant will again be mapped to the hash element 'test' so the constant will be retrieved. The case will then be checked, and will match up, so the value ('Hello') will be returned. When 'Test' is evaulated, it will also map to the same hash element 'test'. The same constant will be retrieved, this time though the case check will fail as 'Test' != 'TEST'. So PHP will assume that Test is a undeclared constant, and as explained above, will return it as a string set to the constant name ('Test'). Hence the script above will print 'Hello Test'. If
they were declared non-case sensitive, the output would be 'Hello Hello', as they were declared non-case sensitive, the output would be 'Hello Hello', as
both point to the same value, without the case test taking place. both point to the same value, without the case test taking place.
( Apologies, this paragraph needs rewritting to make some sense. ) ( Apologies, this paragraph needs rewritting to make some sense. )
</p>
<a name="n11"></a><H3>21.2.8 Shadow classes</H3> <H3><a name="Php_nn11"></a>23.2.8 Shadow classes</H3>
<p>
To avoid having to call the various accessor function to get at structures or To avoid having to call the various accessor function to get at structures or
class members, we can turn C structs and C++ classes into PHP classes that class members, we can turn C structs and C++ classes into PHP classes that
can be be used directly in PHP scripts as objects and object methods. This is done by writing additional PHP code that builds PHP classes on top of the low-level SWIG interface. These PHP classes "shadow" an underlying C/C++ class. can be be used directly in PHP scripts as objects and object methods. This is done by writing additional PHP code that builds PHP classes on top of the low-level SWIG interface. These PHP classes "shadow" an underlying C/C++ class.
</p>
<p>
To have SWIG create shadow classes, use the <tt>-shadow</tt> option : To have SWIG create shadow classes, use the <tt>-shadow</tt> option :
<p><p><blockquote><pre>% swig -php4 -shadow tbc.i </p>
<blockquote><pre>
% swig -php4 -shadow tbc.i
</pre></blockquote> </pre></blockquote>
<p> <p>
This will produce the same files as before except that the final module This will produce the same files as before except that the final module
will declare internal PHP classes with the same names as the classes in will declare internal PHP classes with the same names as the classes in
your .i file. No longer are the shadow classes defined in your .i file. No longer are the shadow classes defined in
the <tt>.php</tt> file, it will not contain significantly more support PHP the <tt>.php</tt> file, it will not contain significantly more support PHP
code. code.
</p>
<p>
For the most part, the code is the same except that we can now access members of For the most part, the code is the same except that we can now access members of
complex data structures using <tt>-&gt;</tt> instead of the low level access or complex data structures using <tt>-&gt;</tt> instead of the low level access or
functions like before. functions like before.
</p>
<p>
.... ( more examples on the way ) .... .... ( more examples on the way ) ....
</p>
<a name="n12"></a><H3>21.2.9 Constructors and Destructers</H3> <H3><a name="Php_nn12"></a>23.2.9 Constructors and Destructers</H3>
<p>
Constructors are used in PHP as in C++, they are called when the object is Constructors are used in PHP as in C++, they are called when the object is
created and any arguments are passed to them. However, function overloading created and any arguments are passed to them. However, function overloading
is not allowed in PHP so only one constructor can be used. This creates a is not allowed in PHP so only one constructor can be used. This creates a
problem when copying objects, as we cannot avoid creating a whole new one problem when copying objects, as we cannot avoid creating a whole new one
when all we want is to make it point to the same value as the original. This when all we want is to make it point to the same value as the original. This
is currently worked around by doing the following, is currently worked around by doing the following,
</p>
<ul> <ul>
<li>Create the new PHP object <li>Create the new PHP object
<li>Delete the PHP objects pointer to the C object <li>Delete the PHP objects pointer to the C object
<li>Set the PHP object's pointer to the same as the original PHP object's pointer. <li>Set the PHP object's pointer to the same as the original PHP object's pointer.
</ul> </ul>
<p>
This is rather convoluted and hopefully will be improved upon in a later This is rather convoluted and hopefully will be improved upon in a later
release. release.
<p><p> </p>
<p>
Because the internal wrapped objects are wrapped in PHP resources, PHP Because the internal wrapped objects are wrapped in PHP resources, PHP
handles the cleaning up when there are no more references to the wrapped handles the cleaning up when there are no more references to the wrapped
object. 'RegisterShutdownFunction' is no longer needed for this. object. 'RegisterShutdownFunction' is no longer needed for this.
I am not sure if PHP resources are all freed at the end of a script, or I am not sure if PHP resources are all freed at the end of a script, or
when they each go out of scope. when they each go out of scope.
</p>
<a name="n13"></a><H3>21.2.10 Static Member Variables</H3> <H3><a name="Php_nn13"></a>23.2.10 Static Member Variables</H3>
Class variables are not supported in PHP, however class functions are, using Class variables are not supported in PHP, however class functions are, using
@ -398,8 +486,11 @@ class Ko {
}; };
</pre></blockquote> </pre></blockquote>
<p> <p>
would be accessed in PHP as, would be accessed in PHP as,
</p>
<blockquote><pre> <blockquote><pre>
dl("libexample.so"); dl("libexample.so");
@ -416,7 +507,7 @@ echo "There has now been " . Ko::threats() . " threats\n";
</pre></blockquote> </pre></blockquote>
<a name="n14"></a><H3>21.2.11 PHP4 Pragmas</H3> <H3><a name="Php_nn14"></a>23.2.11 PHP4 Pragmas</H3>
There are a few pragmas understood by the PHP4 module. The first, There are a few pragmas understood by the PHP4 module. The first,
@ -445,21 +536,28 @@ function is called.
%include "example.h" %include "example.h"
</pre></blockquote> </pre></blockquote>
<a name="n15"></a><H3>21.2.12 Building extensions into php</H3> <H3><a name="Php_nn15"></a>23.2.12 Building extensions into php</H3>
<p>
This method, selected with the <tt>-phpfull</tt> command line switch, involves This method, selected with the <tt>-phpfull</tt> command line switch, involves
rebuilding the entire php source tree. Whilst more complicated to build, rebuilding the entire php source tree. Whilst more complicated to build,
it does mean that the extension is then available without having to load it it does mean that the extension is then available without having to load it
in each script. in each script.
</p>
<p> <p>
After running swig with the -phpfull switch, you will be left with a shockingly After running swig with the -phpfull switch, you will be left with a shockingly
similiar set of files to the previous build process. However you will then need similiar set of files to the previous build process. However you will then need
to move these files to a subdirectory within the php source tree, this subdirectory you will need to create under the ext directory, with the name of the extension ( e.g mkdir php-4.0.6/ext/modulename .) to move these files to a subdirectory within the php source tree, this subdirectory you will need to create under the ext directory, with the name of the extension ( e.g mkdir php-4.0.6/ext/modulename .)
</p>
<p> <p>
After moving the files into this directory, you will need to run the 'buildall' After moving the files into this directory, you will need to run the 'buildall'
script in the php source directory. This rebuilds the configure script script in the php source directory. This rebuilds the configure script
and includes the extra command line arguments from the module you have added. and includes the extra command line arguments from the module you have added.
</p>
<p> <p>
Before running the generated configure file, you may need to edit the <tt> Before running the generated configure file, you may need to edit the <tt>
Makefile.in</tt>. This contains the names of the source files to compile ( Makefile.in</tt>. This contains the names of the source files to compile (
@ -468,13 +566,18 @@ link in. If their are extra C files to compile you will need to add them
to the Makefile, or add the names of libraries if they are needed. to the Makefile, or add the names of libraries if they are needed.
In most cases <tt>Makefile.in</tt> will be complete, especially if you In most cases <tt>Makefile.in</tt> will be complete, especially if you
make use of <tt>-withlibs</tt> and <tt>-withincs</tt> make use of <tt>-withlibs</tt> and <tt>-withincs</tt>
</p>
<blockquote><pre> <blockquote><pre>
swig -php4 -phpfull -withlibs "xapian omquery" --withincs "om.h" swig -php4 -phpfull -withlibs "xapian omquery" --withincs "om.h"
</pre></blockquote> </pre></blockquote>
<p> <p>
Will include in the config.m4 and Makefile.in search for libxapian.a or Will include in the config.m4 and Makefile.in search for libxapian.a or
libxapian.so and search for libomquery.a or libomquery.so as well as a libxapian.so and search for libomquery.a or libomquery.so as well as a
search for om.h search for om.h
</p>
<p> <p>
You then need to run the configure command and pass the necessary command You then need to run the configure command and pass the necessary command
line arguments to enable your module ( by default this is --enable-modulename, line arguments to enable your module ( by default this is --enable-modulename,
@ -482,12 +585,16 @@ but this can be changed by editing the config.m4 file in the modules directory
before running the buildall script. In addition, extra tests can be added to before running the buildall script. In addition, extra tests can be added to
the config.m4 file to ensure the correct libraries and header files are the config.m4 file to ensure the correct libraries and header files are
installed.) installed.)
</p>
<p> <p>
Once configure has completed, you can run make to build php. If this all Once configure has completed, you can run make to build php. If this all
compiles correctly, you should end up with a php executable/library compiles correctly, you should end up with a php executable/library
which contains your new module. You can test it with a php script which which contains your new module. You can test it with a php script which
does not have the 'dl' command as used above. does not have the 'dl' command as used above.
<a name="n16"></a><H3>21.2.13 To be furthered...</H3> </p>
<H3><a name="Php_nn16"></a>23.2.13 To be furthered...</H3>
</body> </body>

View file

@ -5,44 +5,48 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>5 SWIG and Pike</H1> <H1><a name="Pike"></a>24 SWIG and Pike</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">Preliminaries</a> <li><a href="#Pike_nn2">Preliminaries</a>
<ul> <ul>
<li><a href="#n3">Running SWIG</a> <li><a href="#Pike_nn3">Running SWIG</a>
<li><a href="#n4">Getting the right header files</a> <li><a href="#Pike_nn4">Getting the right header files</a>
<li><a href="#n5">Using your module</a> <li><a href="#Pike_nn5">Using your module</a>
</ul> </ul>
<li><a href="#n6">Basic C/C++ Mapping</a> <li><a href="#Pike_nn6">Basic C/C++ Mapping</a>
<ul> <ul>
<li><a href="#n7">Modules</a> <li><a href="#Pike_nn7">Modules</a>
<li><a href="#n8">Functions</a> <li><a href="#Pike_nn8">Functions</a>
<li><a href="#n9">Global variables</a> <li><a href="#Pike_nn9">Global variables</a>
<li><a href="#n10">Constants and enumerated types</a> <li><a href="#Pike_nn10">Constants and enumerated types</a>
<li><a href="#n11">Constructors and Destructors</a> <li><a href="#Pike_nn11">Constructors and Destructors</a>
<li><a href="#n12">Static Members</a> <li><a href="#Pike_nn12">Static Members</a>
</ul> </ul>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
<p>
This chapter describes SWIG support for Pike. As of this writing, the This chapter describes SWIG support for Pike. As of this writing, the
SWIG Pike module is still under development and is not considered SWIG Pike module is still under development and is not considered
ready for prime time. The Pike module is being developed against the ready for prime time. The Pike module is being developed against the
Pike 7.4.10 release and may not be compatible with previous versions Pike 7.4.10 release and may not be compatible with previous versions
of Pike.<p> of Pike.
</p>
<p>
This chapter covers most SWIG features, but certain low-level details This chapter covers most SWIG features, but certain low-level details
are covered in less depth than in earlier chapters. At the very are covered in less depth than in earlier chapters. At the very
least, make sure you read the "<a least, make sure you read the "<a href="SWIG.html#SWIG">SWIG Basics</a>"
href="file:///home/jlj/src/SWIG/Doc/Manual/SWIG.html">SWIG Basics</a>"
chapter.<br> chapter.<br>
<a name="n2"></a><H2>5.1 Preliminaries</H2> </p>
<H2><a name="Pike_nn2"></a>24.1 Preliminaries</H2>
<a name="n3"></a><H3>5.1.1 Running SWIG</H3> <H3><a name="Pike_nn3"></a>24.1.1 Running SWIG</H3>
Suppose that you defined a SWIG module such as the following: Suppose that you defined a SWIG module such as the following:
@ -57,35 +61,46 @@ If you're building a C++ extension, be sure to add the <tt>-c++</tt> option:
<blockquote> <blockquote>
<pre>$ <b>swig -c++ -pike example.i</b><br></pre> <pre>$ <b>swig -c++ -pike example.i</b><br></pre>
</blockquote> </blockquote>
<p>
This creates a single source file named <tt>example_wrap.c</tt> (or <tt>example_wrap.cxx</tt>, if you This creates a single source file named <tt>example_wrap.c</tt> (or <tt>example_wrap.cxx</tt>, if you
ran SWIG with the <tt>-c++</tt> option). ran SWIG with the <tt>-c++</tt> option).
The SWIG-generated source file contains the low-level wrappers that need The SWIG-generated source file contains the low-level wrappers that need
to be compiled and linked with the rest of your C/C++ application to to be compiled and linked with the rest of your C/C++ application to
create an extension module.<p> create an extension module.
</p>
<p>
The name of the wrapper file is derived from the name of the input The name of the wrapper file is derived from the name of the input
file. For example, if the input file is <tt>example.i</tt>, the name file. For example, if the input file is <tt>example.i</tt>, the name
of the wrapper file is <tt>example_wrap.c</tt>. To change this, you of the wrapper file is <tt>example_wrap.c</tt>. To change this, you
can use the <tt>-o</tt> option: can use the <tt>-o</tt> option:
</p>
<blockquote> <blockquote>
<pre>$ <b>swig -pike -o pseudonym.c example.i</b><br></pre> <pre>$ <b>swig -pike -o pseudonym.c example.i</b><br></pre>
</blockquote> </blockquote>
<a name="n4"></a><H3>5.1.2 Getting the right header files</H3> <H3><a name="Pike_nn4"></a>24.1.2 Getting the right header files</H3>
<p>
In order to compile the C/C++ wrappers, the compiler needs to know the In order to compile the C/C++ wrappers, the compiler needs to know the
path to the Pike header files. These files are usually contained in a path to the Pike header files. These files are usually contained in a
directory such as directory such as
<p> </p> </p>
<blockquote> <blockquote>
<pre>/usr/local/pike/7.4.10/include/pike<br></pre> <pre>/usr/local/pike/7.4.10/include/pike<br></pre>
</blockquote> </blockquote>
<p>
There doesn't seem to be any way to get Pike itself to reveal the There doesn't seem to be any way to get Pike itself to reveal the
location of these files, so you may need to hunt around for them. location of these files, so you may need to hunt around for them.
You're looking for files with the names <tt>global.h</tt>, <tt>program.h</tt> You're looking for files with the names <tt>global.h</tt>, <tt>program.h</tt>
and so on. and so on.
</p>
<a name="n5"></a><H3>5.1.3 Using your module</H3> <H3><a name="Pike_nn5"></a>24.1.3 Using your module</H3>
To use your module, simply use Pike's <tt>import</tt> statement: To use your module, simply use Pike's <tt>import</tt> statement:
@ -98,10 +113,10 @@ Pike v7.4 release 10 running Hilfe v3.5 (Incremental Pike Frontend)
(1) Result: 24 (1) Result: 24
</pre></blockquote> </pre></blockquote>
<a name="n6"></a><H2>5.2 Basic C/C++ Mapping</H2> <H2><a name="Pike_nn6"></a>24.2 Basic C/C++ Mapping</H2>
<a name="n7"></a><H3>5.2.1 Modules</H3> <H3><a name="Pike_nn7"></a>24.2.1 Modules</H3>
All of the code for a given SWIG module is wrapped into a single Pike All of the code for a given SWIG module is wrapped into a single Pike
@ -110,7 +125,7 @@ module ultimately determines the module's name (as far as Pike is
concerned), SWIG's <tt>%module</tt> directive doesn't really have any concerned), SWIG's <tt>%module</tt> directive doesn't really have any
significance. significance.
<a name="n8"></a><H3>5.2.2 Functions</H3> <H3><a name="Pike_nn8"></a>24.2.2 Functions</H3>
Global functions are wrapped as new Pike built-in functions. For Global functions are wrapped as new Pike built-in functions. For
@ -131,7 +146,7 @@ exactly as you'd expect it to:
(1) Result: 24 (1) Result: 24
</pre></blockquote> </pre></blockquote>
<a name="n9"></a><H3>5.2.3 Global variables</H3> <H3><a name="Pike_nn9"></a>24.2.3 Global variables</H3>
Global variables are currently wrapped as a pair of of functions, one to get Global variables are currently wrapped as a pair of of functions, one to get
@ -156,19 +171,19 @@ will result in two functions, <tt>Foo_get()</tt> and <tt>Foo_set()</tt>:
(3) Result: 3.141590 (3) Result: 3.141590
</pre></blockquote> </pre></blockquote>
<a name="n10"></a><H3>5.2.4 Constants and enumerated types</H3> <H3><a name="Pike_nn10"></a>24.2.4 Constants and enumerated types</H3>
Enumerated types in C/C++ declarations are wrapped as Pike constants, Enumerated types in C/C++ declarations are wrapped as Pike constants,
not as Pike enums. not as Pike enums.
<a name="n11"></a><H3>5.2.5 Constructors and Destructors</H3> <H3><a name="Pike_nn11"></a>24.2.5 Constructors and Destructors</H3>
Constructors are wrapped as <tt>create()</tt> methods, and destructors are Constructors are wrapped as <tt>create()</tt> methods, and destructors are
wrapped as <tt>destroy()</tt> methods, for Pike classes. wrapped as <tt>destroy()</tt> methods, for Pike classes.
<a name="n12"></a><H3>5.2.6 Static Members</H3> <H3><a name="Pike_nn12"></a>24.2.6 Static Members</H3>
Since Pike doesn't support static methods or data for Pike classes, static Since Pike doesn't support static methods or data for Pike classes, static
@ -190,4 +205,4 @@ public:
SWIG will generate a <tt>Shape_print()</tt> method that invokes the static SWIG will generate a <tt>Shape_print()</tt> method that invokes the static
<tt>Shape::print()</tt> member function, as well as a pair of methods, <tt>Shape::print()</tt> member function, as well as a pair of methods,
<tt>Shape_nshapes_get()</tt> and <tt>Shape_nshapes_set()</tt>, to get and set <tt>Shape_nshapes_get()</tt> and <tt>Shape_nshapes_set()</tt>, to get and set
the value of <tt>Shape::nshapes</tt>. the value of <tt>Shape::nshapes</tt>.

View file

@ -5,28 +5,28 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>0 Preface</H1> <H1><a name="Preface"></a>1 Preface</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">Introduction</a> <li><a href="#Preface_nn2">Introduction</a>
<li><a href="#n3">Special Introduction for Version 1.3</a> <li><a href="#Preface_nn3">Special Introduction for Version 1.3</a>
<li><a href="#n4">SWIG Versions</a> <li><a href="#Preface_nn4">SWIG Versions</a>
<li><a href="#n5">SWIG resources</a> <li><a href="#Preface_nn5">SWIG resources</a>
<li><a href="#n6">Prerequisites</a> <li><a href="#Preface_nn6">Prerequisites</a>
<li><a href="#n7">Organization of this manual</a> <li><a href="#Preface_nn7">Organization of this manual</a>
<li><a href="#n8">How to avoid reading the manual</a> <li><a href="#Preface_nn8">How to avoid reading the manual</a>
<li><a href="#n9">Backwards Compatibility</a> <li><a href="#Preface_nn9">Backwards Compatibility</a>
<li><a href="#n10">Credits</a> <li><a href="#Preface_nn10">Credits</a>
<li><a href="#n11">Bug reports</a> <li><a href="#Preface_nn11">Bug reports</a>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
<a name="n2"></a><H2>0.1 Introduction</H2> <H2><a name="Preface_nn2"></a>1.1 Introduction</H2>
SWIG is a software development tool for building scripting language SWIG (Simplified Wrapper and Interface Generator) is a software development tool for building scripting language
interfaces to C and C++ programs. Originally developed in 1995, SWIG was interfaces to C and C++ programs. Originally developed in 1995, SWIG was
first used by scientists in the Theoretical Physics Division at Los Alamos National Laboratory for first used by scientists in the Theoretical Physics Division at Los Alamos National Laboratory for
building user interfaces to simulation codes running on the Connection building user interfaces to simulation codes running on the Connection
@ -44,8 +44,7 @@ has since evolved into a general purpose tool that is used in a wide
variety of applications--in fact almost anything where C/C++ programming variety of applications--in fact almost anything where C/C++ programming
is involved. is involved.
<p> <H2><a name="Preface_nn3"></a>1.2 Special Introduction for Version 1.3</H2>
<a name="n3"></a><H2>0.2 Special Introduction for Version 1.3</H2>
Since SWIG was released in 1996, its user base and applicability has Since SWIG was released in 1996, its user base and applicability has
@ -57,8 +56,7 @@ all of the ANSI C++ standard and approximately ten target languages
including Guile, Java, Mzscheme, Ocaml, Perl, Pike, PHP, Python, Ruby, including Guile, Java, Mzscheme, Ocaml, Perl, Pike, PHP, Python, Ruby,
and Tcl. and Tcl.
<p> <H2><a name="Preface_nn4"></a>1.3 SWIG Versions</H2>
<a name="n4"></a><H2>0.3 SWIG Versions</H2>
For several years, the most stable version of SWIG has been release For several years, the most stable version of SWIG has been release
@ -69,10 +67,10 @@ represent stable releases. Currently, developers are working to
create a stable SWIG-2.0 release (Maybe in 2003). Don't let the development status create a stable SWIG-2.0 release (Maybe in 2003). Don't let the development status
of SWIG-1.3 scare you---it is much more stable (and capable) than SWIG-1.1p5. of SWIG-1.3 scare you---it is much more stable (and capable) than SWIG-1.1p5.
<a name="n5"></a><H2>0.4 SWIG resources</H2> <H2><a name="Preface_nn5"></a>1.4 SWIG resources</H2>
The official location of SWIG related material is<p> The official location of SWIG related material is
<blockquote><pre> <blockquote><pre>
<a href="http://www.swig.org">http://www.swig.org</a> <a href="http://www.swig.org">http://www.swig.org</a>
@ -85,27 +83,31 @@ implementation tricks.
<p> <p>
You can also subscribe to the SWIG mailing list by visiting the page You can also subscribe to the SWIG mailing list by visiting the page
</p>
<p> <blockquote><pre>
<blockquote><pre><a href="http://mailman.cs.uchicago.edu/listinfo/swig">http://mailman.cs.uchicago.edu/listinfo/swig</a> <a href="http://www.swig.org/mail.html">http://www.swig.org/mail.html</a>
</pre></blockquote> </pre></blockquote>
<p> <p>
The mailing list often discusses some of the more technical aspects of The mailing list often discusses some of the more technical aspects of
SWIG along with information about beta releases and future work.<p> SWIG along with information about beta releases and future work.
</p>
<p> <p>
CVS access to the latest version of SWIG is also available. More information CVS access to the latest version of SWIG is also available. More information
about this can be obtained at: about this can be obtained at:
</p>
<p> <blockquote><pre>
<blockquote><pre><a href="http://www.swig.org/cvs.html">http://www.swig.org/cvs.html</a> <a href="http://www.swig.org/cvs.html">http://www.swig.org/cvs.html</a>
</pre></blockquote> </pre></blockquote>
<a name="n6"></a><H2>0.5 Prerequisites</H2> <H2><a name="Preface_nn6"></a>1.5 Prerequisites</H2>
<p>
This manual assumes that you know how to write C/C++ programs and that you This manual assumes that you know how to write C/C++ programs and that you
have at least heard of scripting languages such as have at least heard of scripting languages such as
Tcl, Python, and Perl. A detailed knowledge of these scripting Tcl, Python, and Perl. A detailed knowledge of these scripting
@ -116,6 +118,7 @@ However, you should be reasonably familiar with the use of
compilers, linkers, and makefiles since making compilers, linkers, and makefiles since making
scripting language extensions is somewhat more complicated than scripting language extensions is somewhat more complicated than
writing a normal C program. writing a normal C program.
</p>
<p> <p>
Recent SWIG releases have become significantly more capable in Recent SWIG releases have become significantly more capable in
@ -126,7 +129,7 @@ However, this isn't meant to be a tutorial on C++ programming. For many
of the gory details, you will almost certainly want to consult a good C++ reference. If you don't program of the gory details, you will almost certainly want to consult a good C++ reference. If you don't program
in C++, you may just want to skip those parts of the manual. in C++, you may just want to skip those parts of the manual.
<a name="n7"></a><H2>0.6 Organization of this manual</H2> <H2><a name="Preface_nn7"></a>1.6 Organization of this manual</H2>
The first few chapters of this manual describe SWIG in general and The first few chapters of this manual describe SWIG in general and
@ -137,7 +140,7 @@ can probably skip to that chapter and find almost everything you need
to know. Caveat: we are currently working on a documentation rewrite and many to know. Caveat: we are currently working on a documentation rewrite and many
of the older language module chapters are still somewhat out of date. of the older language module chapters are still somewhat out of date.
<a name="n8"></a><H2>0.7 How to avoid reading the manual</H2> <H2><a name="Preface_nn8"></a>1.7 How to avoid reading the manual</H2>
If you hate reading manuals, glance at the "Introduction" which If you hate reading manuals, glance at the "Introduction" which
@ -147,7 +150,7 @@ SWIG. After that, simply use the language-specific chapters as a reference.
The SWIG distribution also comes with a large directory of The SWIG distribution also comes with a large directory of
examples that illustrate different topics. examples that illustrate different topics.
<a name="n9"></a><H2>0.8 Backwards Compatibility</H2> <H2><a name="Preface_nn9"></a>1.8 Backwards Compatibility</H2>
If you are a previous user of SWIG, don't expect recent versions of If you are a previous user of SWIG, don't expect recent versions of
@ -164,7 +167,7 @@ for the large number of new features that have been
added---namespaces, templates, smart pointers, overloaded methods, added---namespaces, templates, smart pointers, overloaded methods,
operators, and more. operators, and more.
<a name="n10"></a><H2>0.9 Credits</H2> <H2><a name="Preface_nn10"></a>1.9 Credits</H2>
SWIG is an unfunded project that would not be possible without the SWIG is an unfunded project that would not be possible without the
@ -187,7 +190,7 @@ Gary Holt have provided a great deal of input on improving SWIG's
Perl5 implementation. Kevin Butler contributed the first Windows NT Perl5 implementation. Kevin Butler contributed the first Windows NT
port. port.
<a name="n11"></a><H2>0.10 Bug reports</H2> <H2><a name="Preface_nn11"></a>1.10 Bug reports</H2>
Although every attempt has been made to make SWIG bug-free, we are also trying Although every attempt has been made to make SWIG bug-free, we are also trying
@ -200,7 +203,7 @@ core dump occurred), corresponding portions of the SWIG interface file
used, and any important pieces of the SWIG generated wrapper code. We used, and any important pieces of the SWIG generated wrapper code. We
can only fix bugs if we know about them. can only fix bugs if we know about them.
<p><hr> <hr>
<address>SWIG 1.3 - Last Modified : March 9, 2003</address> <address>SWIG 1.3 - Last Modified : March 9, 2003</address>
</body> </body>
</html> </html>

View file

@ -5,17 +5,18 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>6 Preprocessing</H1> <H1><a name="Preprocessor"></a>7 Preprocessing</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">File inclusion</a> <li><a href="#Preprocessor_nn2">File inclusion</a>
<li><a href="#n3">File imports</a> <li><a href="#Preprocessor_nn3">File imports</a>
<li><a href="#n4">Conditional Compilation</a> <li><a href="#Preprocessor_nn4">Conditional Compilation</a>
<li><a href="#n5">Macro Expansion</a> <li><a href="#Preprocessor_nn5">Macro Expansion</a>
<li><a href="#n6">SWIG Macros</a> <li><a href="#Preprocessor_nn6">SWIG Macros</a>
<li><a href="#n7">C99 and GNU Extensions</a> <li><a href="#Preprocessor_nn7">C99 and GNU Extensions</a>
<li><a href="#n8">Preprocessing and %{ ... %} blocks</a> <li><a href="#Preprocessor_nn8">Preprocessing and %{ ... %} blocks</a>
<li><a href="#n9">Preprocessing and { ... }</a> <li><a href="#Preprocessor_nn9">Preprocessing and { ... }</a>
<li><a href="#Preprocessor_nn10">Viewing preprocessor output</a>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -26,7 +27,7 @@ supports the standard preprocessor directives and macro expansion rules.
However, a number of modifications and enhancements have been made. This However, a number of modifications and enhancements have been made. This
chapter describes some of these modifications. chapter describes some of these modifications.
<a name="n2"></a><H2>6.1 File inclusion</H2> <H2><a name="Preprocessor_nn2"></a>7.1 File inclusion</H2>
To include another file into a SWIG interface, use the <tt>%include</tt> directive To include another file into a SWIG interface, use the <tt>%include</tt> directive
@ -48,7 +49,7 @@ By default, the <tt>#include</tt> is ignored unless you run SWIG with the
is that you often don't want SWIG to try and wrap everything included is that you often don't want SWIG to try and wrap everything included
in standard header system headers and auxilliary files. in standard header system headers and auxilliary files.
<a name="n3"></a><H2>6.2 File imports</H2> <H2><a name="Preprocessor_nn3"></a>7.2 File imports</H2>
SWIG provides another file inclusion directive with the <tt>%import</tt> directive. SWIG provides another file inclusion directive with the <tt>%import</tt> directive.
@ -73,15 +74,16 @@ The <tt>-importall</tt> directive tells SWIG to follow all <tt>#include</tt> sta
as imports. This might be useful if you want to extract type definitions from system as imports. This might be useful if you want to extract type definitions from system
header files without generating any wrappers. header files without generating any wrappers.
<a name="n4"></a><H2>6.3 Conditional Compilation</H2> <H2><a name="Preprocessor_nn4"></a>7.3 Conditional Compilation</H2>
<p>
SWIG fully supports the use of <tt>#if</tt>, <tt>#ifdef</tt>, SWIG fully supports the use of <tt>#if</tt>, <tt>#ifdef</tt>,
<tt>#ifndef</tt>, <tt>#else</tt>, <tt>#endif</tt> to conditionally <tt>#ifndef</tt>, <tt>#else</tt>, <tt>#endif</tt> to conditionally
include parts of an interface. The following symbols are predefined include parts of an interface. The following symbols are predefined
by SWIG when it is parsing the interface: by SWIG when it is parsing the interface:
</p>
<p>
<blockquote><pre> <blockquote><pre>
SWIG Always defined when SWIG is processing a file SWIG Always defined when SWIG is processing a file
SWIGMAC Defined when running SWIG on the Macintosh SWIGMAC Defined when running SWIG on the Macintosh
@ -116,13 +118,15 @@ __cplusplus Defined when -c++ option used
</pre> </pre>
</blockquote> </blockquote>
<p>
Interface files can look at these symbols as necessary to change the Interface files can look at these symbols as necessary to change the
way in which an interface is generated or to mix SWIG directives with way in which an interface is generated or to mix SWIG directives with
C code. These symbols are also defined within the C code generated by C code. These symbols are also defined within the C code generated by
SWIG (except for the symbol `<tt>SWIG</tt>' which is only defined SWIG (except for the symbol `<tt>SWIG</tt>' which is only defined
within the SWIG compiler).<p> within the SWIG compiler).
</p>
<a name="n5"></a><H2>6.4 Macro Expansion</H2> <H2><a name="Preprocessor_nn5"></a>7.4 Macro Expansion</H2>
Traditional preprocessor macros can be used in SWIG interfaces. Be aware that the <tt>#define</tt> statement Traditional preprocessor macros can be used in SWIG interfaces. Be aware that the <tt>#define</tt> statement
@ -140,6 +144,7 @@ you may get some extra constants such as <tt>_FOO_H</tt> showing up in the scrip
<p> <p>
More complex macros can be defined in the standard way. For example: More complex macros can be defined in the standard way. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -157,18 +162,19 @@ The following operators can appear in macro definitions:
<ul> <ul>
<li><tt>#x</tt><br> <li><tt>#x</tt><br>
Converts macro argument <tt>x</tt> to a string surrounded by double quotes ("x"). Converts macro argument <tt>x</tt> to a string surrounded by double quotes ("x").
</li>
<p>
<li><tt>x ## y</tt><br> <li><tt>x ## y</tt><br>
Concatenates x and y together to form <tt>xy</tt>. Concatenates x and y together to form <tt>xy</tt>.
</li>
<p>
<li><tt>`x`</tt><br> <li><tt>`x`</tt><br>
If <tt>x</tt> is a string surrounded by double quotes, do nothing. Otherwise, turn into a string If <tt>x</tt> is a string surrounded by double quotes, do nothing. Otherwise, turn into a string
like <tt>#x</tt>. This is a non-standard SWIG extension. like <tt>#x</tt>. This is a non-standard SWIG extension.
</li>
</ul> </ul>
<a name="n6"></a><H2>6.5 SWIG Macros</H2> <H2><a name="Preprocessor_nn6"></a>7.5 SWIG Macros</H2>
SWIG provides an enhanced macro capability with the <tt>%define</tt> and <tt>%enddef</tt> directives. SWIG provides an enhanced macro capability with the <tt>%define</tt> and <tt>%enddef</tt> directives.
@ -208,8 +214,9 @@ directives except for nested <tt>%define</tt> statements.
The SWIG macro capability is a very quick and easy way to generate large amounts of code. In fact, The SWIG macro capability is a very quick and easy way to generate large amounts of code. In fact,
many of SWIG's advanced features and libraries are built using this mechanism (such as C++ template many of SWIG's advanced features and libraries are built using this mechanism (such as C++ template
support). support).
</p>
<a name="n7"></a><H2>6.6 C99 and GNU Extensions</H2> <H2><a name="Preprocessor_nn7"></a>7.6 C99 and GNU Extensions</H2>
SWIG-1.3.12 and newer releases support variadic preprocessor macros. For example: SWIG-1.3.12 and newer releases support variadic preprocessor macros. For example:
@ -227,10 +234,11 @@ macros defined using <tt>%define</tt>.
<p> <p>
SWIG allows a variable number of arguments to be empty. However, this often results SWIG allows a variable number of arguments to be empty. However, this often results
in an extra comma (,) and syntax error in the resulting expansion. For example: in an extra comma (,) and syntax error in the resulting expansion. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
DEBUGF("hello"); --> fprintf(stderr,"hello",); DEBUGF("hello"); --&gt; fprintf(stderr,"hello",);
</pre> </pre>
</blockquote> </blockquote>
@ -244,6 +252,7 @@ To get rid of the extra comma, use <tt>##</tt> like this:
<p> <p>
SWIG also supports GNU-style variadic macros. For example: SWIG also supports GNU-style variadic macros. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -255,7 +264,7 @@ SWIG also supports GNU-style variadic macros. For example:
interface building. However, they are used internally to implement a number of interface building. However, they are used internally to implement a number of
SWIG directives and are provided to make SWIG more compatible with C99 code. SWIG directives and are provided to make SWIG more compatible with C99 code.
<a name="n8"></a><H2>6.7 Preprocessing and %{ ... %} blocks</H2> <H2><a name="Preprocessor_nn8"></a>7.7 Preprocessing and %{ ... %} blocks</H2>
The SWIG preprocessor does not process any text enclosed in a code block %{ ... %}. Therefore, The SWIG preprocessor does not process any text enclosed in a code block %{ ... %}. Therefore,
@ -276,7 +285,7 @@ int blah() {
the contents of the <tt>%{ ... %}</tt> block are copied without the contents of the <tt>%{ ... %}</tt> block are copied without
modification to the output (including all preprocessor directives). modification to the output (including all preprocessor directives).
<a name="n9"></a><H2>6.8 Preprocessing and { ... }</H2> <H2><a name="Preprocessor_nn9"></a>7.8 Preprocessing and { ... }</H2>
SWIG always runs the preprocessor on text appearing inside <tt>{ ... }</tt>. However, SWIG always runs the preprocessor on text appearing inside <tt>{ ... }</tt>. However,
@ -310,17 +319,21 @@ to actually go into the wrapper file, prefix the preprocessor directives with <t
</pre> </pre>
</blockquote> </blockquote>
<p>
SWIG will strip the extra <tt>%</tt> and leave the preprocessor directive in the code. SWIG will strip the extra <tt>%</tt> and leave the preprocessor directive in the code.
</p>
<H2><a name="Preprocessor_nn10"></a>7.9 Viewing preprocessor output</H2>
<p> <p>
<a name="n5"></a><H2>6.4 Viewing preprocessor output</H2>
Like many compilers, SWIG supports a <tt>-E</tt> command line option to display the output from the preprocessor. Like many compilers, SWIG supports a <tt>-E</tt> command line option to display the output from the preprocessor.
When the <tt>-E</tt> switch is used, SWIG will not generate any wrappers. When the <tt>-E</tt> switch is used, SWIG will not generate any wrappers.
Instead the results after the preprocessor has run are displayed. Instead the results after the preprocessor has run are displayed.
This might be useful as an aid to debugging and viewing the results of macro expansions. This might be useful as an aid to debugging and viewing the results of macro expansions.
</p>
<p><hr> <hr>
<address>SWIG 1.3 - Last Modified : March 9, 2003</address> <address>SWIG 1.3 - Last Modified : March 9, 2003</address>
</body> </body>

File diff suppressed because it is too large Load diff

View file

@ -4,77 +4,76 @@
<title>SWIG and Ruby</title> <title>SWIG and Ruby</title>
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a> <H1><a name="Ruby"></a>26 SWIG and Ruby</H1>
<a name="n1"></a><H1>23 SWIG and Ruby</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">Preliminaries</a> <li><a href="#Ruby_nn2">Preliminaries</a>
<ul> <ul>
<li><a href="#n3">Running SWIG</a> <li><a href="#Ruby_nn3">Running SWIG</a>
<li><a href="#n4">Getting the right header files</a> <li><a href="#Ruby_nn4">Getting the right header files</a>
<li><a href="#n5">Compiling a dynamic module</a> <li><a href="#Ruby_nn5">Compiling a dynamic module</a>
<li><a href="#n6">Using your module</a> <li><a href="#Ruby_nn6">Using your module</a>
<li><a href="#n7">Static linking</a> <li><a href="#Ruby_nn7">Static linking</a>
<li><a href="#n8">Compilation of C++ extensions</a> <li><a href="#Ruby_nn8">Compilation of C++ extensions</a>
</ul> </ul>
<li><a href="#n9">Building Ruby Extensions under Windows 95/NT</a> <li><a href="#Ruby_nn9">Building Ruby Extensions under Windows 95/NT</a>
<ul> <ul>
<li><a href="#n10">Running SWIG from Developer Studio</a> <li><a href="#Ruby_nn10">Running SWIG from Developer Studio</a>
</ul> </ul>
<li><a href="#n11">The Ruby-to-C/C++ Mapping</a> <li><a href="#Ruby_nn11">The Ruby-to-C/C++ Mapping</a>
<ul> <ul>
<li><a href="#n12">Modules</a> <li><a href="#Ruby_nn12">Modules</a>
<li><a href="#n13">Functions</a> <li><a href="#Ruby_nn13">Functions</a>
<li><a href="#n14">Variable Linking</a> <li><a href="#Ruby_nn14">Variable Linking</a>
<li><a href="#n15">Constants</a> <li><a href="#Ruby_nn15">Constants</a>
<li><a href="#n16">Pointers</a> <li><a href="#Ruby_nn16">Pointers</a>
<li><a href="#n17">Structures</a> <li><a href="#Ruby_nn17">Structures</a>
<li><a href="#n18">C++ classes</a> <li><a href="#Ruby_nn18">C++ classes</a>
<li><a href="#n19">C++ Inheritance</a> <li><a href="#Ruby_nn19">C++ Inheritance</a>
<li><a href="#n20">C++ Overloaded Functions</a> <li><a href="#Ruby_nn20">C++ Overloaded Functions</a>
<li><a href="#n21">C++ Operators</a> <li><a href="#Ruby_nn21">C++ Operators</a>
<li><a href="#n22">C++ namespaces</a> <li><a href="#Ruby_nn22">C++ namespaces</a>
<li><a href="#n23">C++ templates</a> <li><a href="#Ruby_nn23">C++ templates</a>
<li><a href="#n24">C++ Smart Pointers</a> <li><a href="#ruby_cpp_smart_pointers">C++ Smart Pointers</a>
<li><a href="#n25">Cross-Language Polymorphism</a> <li><a href="#Ruby_nn25">Cross-Language Polymorphism</a>
<ul> <ul>
<li><a href="#n26">Exception Unrolling</a> <li><a href="#Ruby_nn26">Exception Unrolling</a>
</ul> </ul>
</ul> </ul>
<li><a href="#n27">Input and output parameters</a> <li><a href="#Ruby_nn27">Input and output parameters</a>
<li><a href="#n28">Simple exception handling </a> <li><a href="#Ruby_nn28">Simple exception handling </a>
<li><a href="#n29">Typemaps</a> <li><a href="#Ruby_nn29">Typemaps</a>
<ul> <ul>
<li><a href="#n30">What is a typemap?</a> <li><a href="#Ruby_nn30">What is a typemap?</a>
<li><a href="#n31">Ruby typemaps</a> <li><a href="#Ruby_nn31">Ruby typemaps</a>
<li><a href="#n32">Typemap variables</a> <li><a href="#Ruby_nn32">Typemap variables</a>
<li><a href="#n33">Useful Functions</a> <li><a href="#Ruby_nn33">Useful Functions</a>
<ul> <ul>
<li><a href="#n34">C Datatypes to Ruby Objects</a> <li><a href="#Ruby_nn34">C Datatypes to Ruby Objects</a>
<li><a href="#n35">Ruby Objects to C Datatypes</a> <li><a href="#Ruby_nn35">Ruby Objects to C Datatypes</a>
<li><a href="#n36">Macros for VALUE</a> <li><a href="#Ruby_nn36">Macros for VALUE</a>
<li><a href="#n37">Exceptions</a> <li><a href="#Ruby_nn37">Exceptions</a>
<li><a href="#n38">Iterators</a> <li><a href="#Ruby_nn38">Iterators</a>
</ul> </ul>
<li><a href="#n39">Typemap Examples</a> <li><a href="#ruby_typemap_examples">Typemap Examples</a>
<li><a href="#n40">Converting a Ruby array to a char **</a> <li><a href="#Ruby_nn40">Converting a Ruby array to a char **</a>
<li><a href="#n41">Collecting arguments in a hash</a> <li><a href="#Ruby_nn41">Collecting arguments in a hash</a>
<li><a href="#n42">Pointer handling</a> <li><a href="#Ruby_nn42">Pointer handling</a>
<ul> <ul>
<li><a href="#n43">Ruby Datatype Wrapping</a> <li><a href="#Ruby_nn43">Ruby Datatype Wrapping</a>
</ul> </ul>
</ul> </ul>
<li><a href="#n44">Operator overloading</a> <li><a href="#ruby_operator_overloading">Operator overloading</a>
<ul> <ul>
<li><a href="#n45">Example: STL Vector to Ruby Array</a> <li><a href="#Ruby_nn45">Example: STL Vector to Ruby Array</a>
</ul> </ul>
<li><a href="#n46">Advanced Topics</a> <li><a href="#Ruby_nn46">Advanced Topics</a>
<ul> <ul>
<li><a href="#n47">Creating Multi-Module Packages</a> <li><a href="#Ruby_nn47">Creating Multi-Module Packages</a>
<li><a href="#n48">Defining Aliases</a> <li><a href="#Ruby_nn48">Defining Aliases</a>
<li><a href="#n49">Predicate Methods</a> <li><a href="#Ruby_nn49">Predicate Methods</a>
<li><a href="#n50">Specifying Mixin Modules</a> <li><a href="#Ruby_nn50">Specifying Mixin Modules</a>
<li><a href="#n51">Interacting with Ruby's Garbage Collector</a> <li><a href="#Ruby_nn51">Interacting with Ruby's Garbage Collector</a>
</ul> </ul>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -83,7 +82,7 @@
<p>This chapter describes SWIG's support of Ruby. </p> <p>This chapter describes SWIG's support of Ruby. </p>
<hr><a name="n2"></a> <hr><a name="n2"></a>
<a name="n2"></a><H2>23.1 Preliminaries</H2> <H2><a name="Ruby_nn2"></a>26.1 Preliminaries</H2>
SWIG 1.3 is known to work with Ruby versions 1.6 and later. Given the SWIG 1.3 is known to work with Ruby versions 1.6 and later. Given the
@ -96,23 +95,22 @@ without dynamic loading, but the compilation process will vary.
<p>This chapter covers most SWIG features, but in less depth than is <p>This chapter covers most SWIG features, but in less depth than is
found in found in
earlier chapters. At the very least, make sure you also read the "<a earlier chapters. At the very least, make sure you also read the "<a
href="SWIG.html">SWIG Basics</a>" chapter. It is also assumed that the href="SWIG.html#SWIG">SWIG Basics</a>" chapter. It is also assumed that the
reader reader
has a basic understanding of Ruby. has a basic understanding of Ruby.
<a name="n3"></a></p>
<a name="n3"></a><H3>23.1.1 Running SWIG</H3> <H3><a name="Ruby_nn3"></a>26.1.1 Running SWIG</H3>
<p> <p>
To build a Ruby module, run SWIG using the <tt>-ruby</tt> option:</p> To build a Ruby module, run SWIG using the <tt>-ruby</tt> option:</p>
<p></p>
<p></p>
<blockquote> <blockquote>
<pre>$ <b>swig -ruby example.i</b> <pre>$ <b>swig -ruby example.i</b>
</pre> </pre>
</blockquote> </blockquote>
If building a C++ extension, add the <tt>-c++</tt> option: If building a C++ extension, add the <tt>-c++</tt> option:
<p></p>
<blockquote> <blockquote>
<pre>$ <b>swig -c++ -ruby example.i</b> <pre>$ <b>swig -c++ -ruby example.i</b>
</pre> </pre>
@ -125,13 +123,16 @@ build a
Ruby extension module. To finish building the module, you need to Ruby extension module. To finish building the module, you need to
compile this compile this
file and link it with the rest of your program. file and link it with the rest of your program.
<a name="n4"></a></p>
<a name="n4"></a><H3>23.1.2 Getting the right header files</H3>
<H3><a name="Ruby_nn4"></a>26.1.2 Getting the right header files</H3>
<p>
In order to compile the wrapper code, the compiler needs the <tt>ruby.h</tt> In order to compile the wrapper code, the compiler needs the <tt>ruby.h</tt>
header file. This file is usually contained in a directory such as header file. This file is usually contained in a directory such as
<p></p> </p>
<blockquote> <blockquote>
<pre>/usr/local/lib/ruby/1.6/i686-linux/ruby.h<br></pre> <pre>/usr/local/lib/ruby/1.6/i686-linux/ruby.h<br></pre>
</blockquote> </blockquote>
@ -149,8 +150,7 @@ can run Ruby to find out. For example:
</pre> </pre>
</blockquote> </blockquote>
<a name="n5"></a> <H3><a name="Ruby_nn5"></a>26.1.3 Compiling a dynamic module</H3>
<a name="n5"></a><H3>23.1.3 Compiling a dynamic module</H3>
Ruby extension modules are typically compiled into shared libraries Ruby extension modules are typically compiled into shared libraries
@ -160,7 +160,7 @@ doing
this vary from platform to platform, your best bet is to follow the this vary from platform to platform, your best bet is to follow the
steps steps
described in the <tt>README.EXT</tt> file from the Ruby distribution: described in the <tt>README.EXT</tt> file from the Ruby distribution:
<p></p>
<ol> <ol>
<li>Create a file called <tt>extconf.rb</tt> that looks like the <li>Create a file called <tt>extconf.rb</tt> that looks like the
following: following:
@ -169,7 +169,6 @@ following:
</blockquote> </blockquote>
</li> </li>
<li>Type the following to build the extension: <li>Type the following to build the extension:
<p></p>
<blockquote> <blockquote>
<pre>$ <b>ruby extconf.rb</b> <pre>$ <b>ruby extconf.rb</b>
$ <b>make</b> $ <b>make</b>
@ -194,7 +193,7 @@ platform.
For example, a typical sequence of commands for the Linux operating For example, a typical sequence of commands for the Linux operating
system system
would look something like this: would look something like this:
<p></p>
<blockquote> <blockquote>
<pre>$ <b>swig -ruby example.i</b> <pre>$ <b>swig -ruby example.i</b>
$ <b>gcc -c example.c</b> $ <b>gcc -c example.c</b>
@ -210,23 +209,22 @@ You might also check the <a
href="http://swig.cs.uchicago.edu/cgi-bin/wiki.pl"> href="http://swig.cs.uchicago.edu/cgi-bin/wiki.pl">
SWIG Wiki</a> for additional information. SWIG Wiki</a> for additional information.
<p> <a name="n6"></a></p> <p> <a name="n6"></a></p>
<a name="n6"></a><H3>23.1.4 Using your module</H3> <H3><a name="Ruby_nn6"></a>26.1.4 Using your module</H3>
Ruby <i>module</i> names must be capitalized, but the convention for Ruby <i>module</i> names must be capitalized, but the convention for
Ruby Ruby
<i>feature</i> names is to use lowercase names. So, for example, the <b>Etc</b> <i>feature</i> names is to use lowercase names. So, for example, the <b>Etc</b>
extension module is imported by requiring the <b>etc</b> feature: extension module is imported by requiring the <b>etc</b> feature:
<pre><blockquote># The feature name begins with a lowercase letter...<br>require 'etc'<br><br># ... but the module name begins with an uppercase letter<br>puts "Your login name: #{Etc.getlogin}"<br></blockquote></pre> <blockquote><pre># The feature name begins with a lowercase letter...<br>require 'etc'<br><br># ... but the module name begins with an uppercase letter<br>puts "Your login name: #{Etc.getlogin}"<br></pre></blockquote>
To stay consistent with this practice, you should always specify a To stay consistent with this practice, you should always specify a
<b>lowercase</b> module name with SWIG's <tt>%module</tt> directive. <b>lowercase</b> module name with SWIG's <tt>%module</tt> directive.
SWIG will automatically correct the resulting Ruby module name for your SWIG will automatically correct the resulting Ruby module name for your
extension. So for example, a SWIG interface file that begins with: extension. So for example, a SWIG interface file that begins with:
<pre><blockquote>%module example<br></blockquote></pre> <blockquote><pre>%module example<br></pre></blockquote>
will result in an extension module using the feature name "example" and will result in an extension module using the feature name "example" and
Ruby module name "Example". Ruby module name "Example".
<a name="n7"></a> <H3><a name="Ruby_nn7"></a>26.1.5 Static linking</H3>
<a name="n7"></a><H3>23.1.5 Static linking</H3>
An alternative approach to dynamic linking is to rebuild the Ruby An alternative approach to dynamic linking is to rebuild the Ruby
@ -243,14 +241,14 @@ adding your directory to the list of extensions in the file, and
finally rebuilding Ruby. finally rebuilding Ruby.
</p> </p>
<p><a name="n8"></a></p> <p><a name="n8"></a></p>
<a name="n8"></a><H3>23.1.6 Compilation of C++ extensions</H3> <H3><a name="Ruby_nn8"></a>26.1.6 Compilation of C++ extensions</H3>
<p> <p>
On most machines, C++ extension modules should be linked using the C++ On most machines, C++ extension modules should be linked using the C++
compiler. For example: compiler. For example:
</p> </p>
<p></p>
<blockquote> <blockquote>
<pre>$ <b>swig -c++ -ruby example.i</b> <pre>$ <b>swig -c++ -ruby example.i</b>
$ <b>g++ -c example.cxx</b> $ <b>g++ -c example.cxx</b>
@ -276,8 +274,7 @@ into your extension, e.g.
<pre>require 'mkmf'<br>$libs = append_library($libs, "supc++")<br>create_makefile('example')<br></pre> <pre>require 'mkmf'<br>$libs = append_library($libs, "supc++")<br>create_makefile('example')<br></pre>
</blockquote> </blockquote>
<hr> <hr>
<a name="n9"></a> <H2><a name="Ruby_nn9"></a>26.2 Building Ruby Extensions under Windows 95/NT</H2>
<a name="n9"></a><H2>23.2 Building Ruby Extensions under Windows 95/NT</H2>
Building a SWIG extension to Ruby under Windows 95/NT is roughly Building a SWIG extension to Ruby under Windows 95/NT is roughly
@ -306,7 +303,7 @@ you may need to download the source distribution to the Ruby package,
as you as you
will need the Ruby header files. will need the Ruby header files.
<p><a name="n10"></a></p> <p><a name="n10"></a></p>
<a name="n10"></a><H3>23.2.1 Running SWIG from Developer Studio</H3> <H3><a name="Ruby_nn10"></a>26.2.1 Running SWIG from Developer Studio</H3>
If you are developing your application within Microsoft developer If you are developing your application within Microsoft developer
@ -314,8 +311,7 @@ studio, SWIG
can be invoked as a custom build option. The process roughly follows can be invoked as a custom build option. The process roughly follows
these these
steps : steps :
<p></p>
<p></p>
<ul> <ul>
<li>Open up a new workspace and use the AppWizard to select a DLL <li>Open up a new workspace and use the AppWizard to select a DLL
project. project.
@ -381,8 +377,7 @@ run
your new Ruby extension, simply run Ruby and use the <tt>require</tt> your new Ruby extension, simply run Ruby and use the <tt>require</tt>
command command
as normal. For example if you have this ruby file run.rb:</p> as normal. For example if you have this ruby file run.rb:</p>
<p></p>
<p></p>
<blockquote> <blockquote>
<pre># file: run.rb<br>require 'Example'<br><br># Call a c function<br>print "Foo = ", Example.Foo, "\n"<br></pre> <pre># file: run.rb<br>require 'Example'<br><br># Call a c function<br>print "Foo = ", Example.Foo, "\n"<br></pre>
</blockquote> </blockquote>
@ -394,17 +389,15 @@ Ruby script from the DOS/Command prompt:
Foo = 3.0 Foo = 3.0
</pre> </pre>
</blockquote> </blockquote>
<p>
</p>
<hr><a name="n11"></a> <hr><a name="n11"></a>
<a name="n11"></a><H2>23.3 The Ruby-to-C/C++ Mapping</H2> <H2><a name="Ruby_nn11"></a>26.3 The Ruby-to-C/C++ Mapping</H2>
This section describes the basics of how SWIG maps C or C++ This section describes the basics of how SWIG maps C or C++
declarations declarations
in your SWIG interface files to Ruby constructs. in your SWIG interface files to Ruby constructs.
<a name="n12"></a> <H3><a name="Ruby_nn12"></a>26.3.1 Modules</H3>
<a name="n12"></a><H3>23.3.1 Modules</H3>
The SWIG <tt>%module</tt> directive specifies the name of the Ruby The SWIG <tt>%module</tt> directive specifies the name of the Ruby
@ -463,13 +456,13 @@ global module,
take care that the names of your constants, classes and methods don't take care that the names of your constants, classes and methods don't
conflict conflict
with any of Ruby's built-in names. with any of Ruby's built-in names.
<a name="n13"></a></p>
<a name="n13"></a><H3>23.3.2 Functions</H3> <H3><a name="Ruby_nn13"></a>26.3.2 Functions</H3>
Global functions are wrapped as Ruby module methods. For example, given Global functions are wrapped as Ruby module methods. For example, given
the SWIG interface file <tt>example.i</tt>: the SWIG interface file <tt>example.i</tt>:
<p></p>
<blockquote> <blockquote>
<pre>%module example<br><br>int fact(int n);<br></pre> <pre>%module example<br><br>int fact(int n);<br></pre>
</blockquote> </blockquote>
@ -480,7 +473,7 @@ and C source file <tt>example.c</tt>:
SWIG will generate a method <i>fact</i> in the <i>Example</i> module SWIG will generate a method <i>fact</i> in the <i>Example</i> module
that that
can be used like so: can be used like so:
<p></p>
<blockquote> <blockquote>
<pre>$ <b>irb</b> <pre>$ <b>irb</b>
irb(main):001:0&gt; <b>require 'example'</b> irb(main):001:0&gt; <b>require 'example'</b>
@ -489,8 +482,7 @@ irb(main):002:0&gt; <b>Example.fact(4)</b>
24 24
</pre> </pre>
</blockquote> </blockquote>
<a name="n14"></a> <H3><a name="Ruby_nn14"></a>26.3.3 Variable Linking</H3>
<a name="n14"></a><H3>23.3.3 Variable Linking</H3>
C/C++ global variables are wrapped as a pair of singleton methods for C/C++ global variables are wrapped as a pair of singleton methods for
@ -504,8 +496,7 @@ variables:
</blockquote> </blockquote>
<p> <p>
Now look at the Ruby interface:</p> Now look at the Ruby interface:</p>
<p></p>
<p></p>
<blockquote> <blockquote>
<pre>$ <b>irb</b> <pre>$ <b>irb</b>
irb(main):001:0&gt; <b>require 'Example'</b> irb(main):001:0&gt; <b>require 'Example'</b>
@ -543,8 +534,7 @@ directive. For example:
The <tt>%immutable</tt> directive stays in effect until it is The <tt>%immutable</tt> directive stays in effect until it is
explicitly explicitly
disabled using <tt>%mutable</tt>. disabled using <tt>%mutable</tt>.
<a name="n15"></a> <H3><a name="Ruby_nn15"></a>26.3.4 Constants</H3>
<a name="n15"></a><H3>23.3.4 Constants</H3>
C/C++ constants are wrapped as module constants initialized to the C/C++ constants are wrapped as module constants initialized to the
@ -555,7 +545,7 @@ appropriate value. To create a constant, use <tt>#define</tt> or the
</blockquote> </blockquote>
Remember to use the :: operator in Ruby to get at these constant Remember to use the :: operator in Ruby to get at these constant
values, e.g. values, e.g.
<p></p>
<blockquote> <blockquote>
<pre>$ <b>irb</b> <pre>$ <b>irb</b>
irb(main):001:0&gt; <b>require 'Example'</b> irb(main):001:0&gt; <b>require 'Example'</b>
@ -564,8 +554,7 @@ irb(main):002:0&gt; <b>Example::PI</b>
3.14159 3.14159
</pre> </pre>
</blockquote> </blockquote>
<a name="n16"></a> <H3><a name="Ruby_nn16"></a>26.3.5 Pointers</H3>
<a name="n16"></a><H3>23.3.5 Pointers</H3>
"Opaque" pointers to arbitrary C/C++ types (i.e. types that aren't "Opaque" pointers to arbitrary C/C++ types (i.e. types that aren't
@ -574,7 +563,7 @@ declared in your SWIG interface file) are wrapped as data objects. So,
for for
example, consider a SWIG interface file containing only the example, consider a SWIG interface file containing only the
declarations: declarations:
<p></p>
<blockquote> <blockquote>
<pre>Foo *get_foo();<br>void set_foo(Foo *foo);<br></pre> <pre>Foo *get_foo();<br>void set_foo(Foo *foo);<br></pre>
</blockquote> </blockquote>
@ -587,15 +576,14 @@ internally generated Ruby class:
</blockquote> </blockquote>
A <tt>NULL</tt> pointer is always represented by the Ruby <tt>nil</tt> A <tt>NULL</tt> pointer is always represented by the Ruby <tt>nil</tt>
object. object.
<a name="n17"></a> <H3><a name="Ruby_nn17"></a>26.3.6 Structures</H3>
<a name="n17"></a><H3>23.3.6 Structures</H3>
C/C++ structs are wrapped as Ruby classes, with accessor methods (i.e. C/C++ structs are wrapped as Ruby classes, with accessor methods (i.e.
"getters" "getters"
and "setters") for all of the struct members. For example, this struct and "setters") for all of the struct members. For example, this struct
declaration: declaration:
<p></p>
<blockquote> <blockquote>
<pre>struct Vector {<br> double x, y;<br>};<br></pre> <pre>struct Vector {<br> double x, y;<br>};<br></pre>
</blockquote> </blockquote>
@ -603,7 +591,7 @@ gets wrapped as a <tt>Vector</tt> class, with Ruby instance methods <tt>x</tt>,
<tt>x=</tt>, <tt>y</tt> and <tt>y=</tt>. These methods can be used to <tt>x=</tt>, <tt>y</tt> and <tt>y=</tt>. These methods can be used to
access access
structure data from Ruby as follows: structure data from Ruby as follows:
<p></p>
<blockquote> <blockquote>
<pre>$ <b>irb</b> <pre>$ <b>irb</b>
irb(main):001:0&gt; <b>require 'Example'</b> irb(main):001:0&gt; <b>require 'Example'</b>
@ -620,7 +608,7 @@ irb(main):004:0&gt; <b>f.x</b>
Similar access is provided for unions and the public data members of Similar access is provided for unions and the public data members of
C++ C++
classes.</p> classes.</p>
<p></p>
<p><tt>const</tt> members of a structure are read-only. Data members <p><tt>const</tt> members of a structure are read-only. Data members
can also be can also be
forced to be read-only using the <tt>%immutable</tt> directive (in forced to be read-only using the <tt>%immutable</tt> directive (in
@ -654,7 +642,7 @@ produces a single accessor function like this:
</blockquote> </blockquote>
If you want to set an array member, you will need to supply a If you want to set an array member, you will need to supply a
"memberin" "memberin"
typemap described in the <a href="#n24">section on typemaps</a>. As a typemap described in the <a href="#ruby_cpp_smart_pointers">section on typemaps</a>. As a
special special
case, SWIG does generate code to set array members of type <tt>char</tt> case, SWIG does generate code to set array members of type <tt>char</tt>
(allowing you to store a Ruby string in the structure). (allowing you to store a Ruby string in the structure).
@ -668,8 +656,7 @@ generates accessor functions such as this:
<blockquote> <blockquote>
<pre>Foo *Bar_f_get(Bar *b) {<br> return &amp;b-&gt;f;<br>}<br><br>void Bar_f_set(Bar *b, Foo *val) {<br> b-&gt;f = *val;<br>}<br></pre> <pre>Foo *Bar_f_get(Bar *b) {<br> return &amp;b-&gt;f;<br>}<br><br>void Bar_f_set(Bar *b, Foo *val) {<br> b-&gt;f = *val;<br>}<br></pre>
</blockquote> </blockquote>
<a name="n18"></a> <H3><a name="Ruby_nn18"></a>26.3.7 C++ classes</H3>
<a name="n18"></a><H3>23.3.7 C++ classes</H3>
Like structs, C++ classes are wrapped by creating a new Ruby class of Like structs, C++ classes are wrapped by creating a new Ruby class of
@ -681,8 +668,8 @@ methods,
and public static member functions are wrapped as Ruby singleton and public static member functions are wrapped as Ruby singleton
methods. So, methods. So,
given the C++ class declaration: given the C++ class declaration:
<p></p>
<p></p>
<blockquote> <blockquote>
<pre>class List {<br>public:<br> List();<br> ~List();<br> int search(char *item);<br> void insert(char *item);<br> void remove(char *item);<br> char *get(int n);<br> int length;<br> static void print(List *l);<br>};<br></pre> <pre>class List {<br>public:<br> List();<br> ~List();<br> int search(char *item);<br> void insert(char *item);<br> void remove(char *item);<br> char *get(int n);<br> int length;<br> static void print(List *l);<br>};<br></pre>
</blockquote> </blockquote>
@ -705,8 +692,7 @@ In Ruby, these functions are used as follows:
<blockquote> <blockquote>
<pre>require 'Example'<br><br>l = Example::List.new<br><br>l.insert("Ale")<br>l.insert("Stout")<br>l.insert("Lager")<br>Example.print(l)<br>l.length()<br>----- produces the following output <br>Lager<br>Stout<br>Ale<br>3<br></pre> <pre>require 'Example'<br><br>l = Example::List.new<br><br>l.insert("Ale")<br>l.insert("Stout")<br>l.insert("Lager")<br>Example.print(l)<br>l.length()<br>----- produces the following output <br>Lager<br>Stout<br>Ale<br>3<br></pre>
</blockquote> </blockquote>
<a name="n19"></a> <H3><a name="Ruby_nn19"></a>26.3.8 C++ Inheritance</H3>
<a name="n19"></a><H3>23.3.8 C++ Inheritance</H3>
The SWIG type-checker is fully aware of C++ inheritance. Therefore, if The SWIG type-checker is fully aware of C++ inheritance. Therefore, if
@ -822,8 +808,7 @@ will otherwise behave as though they inherit from both <tt>Base1</tt>
and <tt>Base2</tt> and <tt>Base2</tt>
(i.e. they exhibit <a href="http://c2.com/cgi/wiki?DuckTyping">"Duck (i.e. they exhibit <a href="http://c2.com/cgi/wiki?DuckTyping">"Duck
Typing"</a>). Typing"</a>).
<a name="n20"></a> <H3><a name="Ruby_nn20"></a>26.3.9 C++ Overloaded Functions</H3>
<a name="n20"></a><H3>23.3.9 C++ Overloaded Functions</H3>
C++ overloaded functions, methods, and constructors are mostly C++ overloaded functions, methods, and constructors are mostly
@ -878,9 +863,9 @@ which declarations appear
in the input does not matter except in situations where ambiguity in the input does not matter except in situations where ambiguity
arises--in this case, the arises--in this case, the
first declaration takes precedence. first declaration takes precedence.
<p>Please refer to the <a href="SWIGPlus.html">"SWIG and C++"</a> <p>Please refer to the <a href="SWIGPlus.html#SWIGPlus">"SWIG and C++"</a>
chapter for more information about overloading. <a name="n21"></a></p> chapter for more information about overloading. <a name="n21"></a></p>
<a name="n21"></a><H3>23.3.10 C++ Operators</H3> <H3><a name="Ruby_nn21"></a>26.3.10 C++ Operators</H3>
For the most part, overloaded operators are handled automatically by For the most part, overloaded operators are handled automatically by
@ -909,9 +894,8 @@ Now, in Ruby, you can do this:
</blockquote> </blockquote>
More details about wrapping C++ operators into Ruby operators is More details about wrapping C++ operators into Ruby operators is
discussed in discussed in
the <a href="#n39">section on operator overloading</a>. the <a href="#ruby_operator_overloading">section on operator overloading</a>.
<a name="n22"></a> <H3><a name="Ruby_nn22"></a>26.3.11 C++ namespaces</H3>
<a name="n22"></a><H3>23.3.11 C++ namespaces</H3>
SWIG is aware of C++ namespaces, but namespace names do not appear in SWIG is aware of C++ namespaces, but namespace names do not appear in
@ -946,8 +930,7 @@ For example, make the module name the same as the namespace and create
extension modules for each namespace separately. If your program extension modules for each namespace separately. If your program
utilizes thousands of small deeply nested namespaces each with utilizes thousands of small deeply nested namespaces each with
identical symbol names, well, then you get what you deserve. identical symbol names, well, then you get what you deserve.
<a name="n23"></a> <H3><a name="Ruby_nn23"></a>26.3.12 C++ templates</H3>
<a name="n23"></a><H3>23.3.12 C++ templates</H3>
C++ templates don't present a huge problem for SWIG. However, in order C++ templates don't present a huge problem for SWIG. However, in order
@ -1000,10 +983,9 @@ float sum(const std::vector&lt;float&gt;&amp; values);
</blockquote> </blockquote>
Obviously, there is a lot more to template wrapping than shown in these Obviously, there is a lot more to template wrapping than shown in these
examples. examples.
More details can be found in the <a href="SWIGPlus.html">SWIG and C++</a> More details can be found in the <a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a>
chapter. chapter.
<a name="n24"></a> <H3><a name="ruby_cpp_smart_pointers"></a>26.3.13 C++ Smart Pointers</H3>
<a name="n24"></a><H3>23.3.13 C++ Smart Pointers</H3>
In certain C++ programs, it is common to use classes that have been In certain C++ programs, it is common to use classes that have been
@ -1040,21 +1022,19 @@ simply use the <tt>__deref__()</tt> method. For example:
<blockquote> <blockquote>
<pre>irb(main):004:0&gt; <b>f = p.__deref__()</b> # Returns underlying Foo *<br></pre> <pre>irb(main):004:0&gt; <b>f = p.__deref__()</b> # Returns underlying Foo *<br></pre>
</blockquote> </blockquote>
<a name="n25"></a> <H3><a name="Ruby_nn25"></a>26.3.14 Cross-Language Polymorphism</H3>
<a name="n25"></a><H3>23.3.14 Cross-Language Polymorphism</H3>
SWIG's Ruby module supports cross-language polymorphism (a.k.a. the SWIG's Ruby module supports cross-language polymorphism (a.k.a. the
"directors" "directors"
feature) similar to that for SWIG's Python module. Rather than feature) similar to that for SWIG's Python module. Rather than
duplicate the duplicate the
information presented in the <a href="Python.html">Python</a> chapter, information presented in the <a href="Python.html#Python">Python</a> chapter,
this this
secton just notes the differences that you need to be aware of when secton just notes the differences that you need to be aware of when
using this using this
feature with Ruby. feature with Ruby.
<a name="n26"></a> <H4><a name="Ruby_nn26"></a>26.3.14.1 Exception Unrolling</H4>
<a name="n26"></a><H4>23.3.14.1 Exception Unrolling</H4>
Whenever a C++ director class routes one of its virtual member function Whenever a C++ director class routes one of its virtual member function
@ -1079,7 +1059,7 @@ Ruby exception
is raised, it will be caught here and a C++ exception is raised in its is raised, it will be caught here and a C++ exception is raised in its
place. place.
<hr><a name="n27"></a> <hr><a name="n27"></a>
<a name="n27"></a><H2>23.4 Input and output parameters</H2> <H2><a name="Ruby_nn27"></a>26.4 Input and output parameters</H2>
A common problem in some C programs is handling parameters passed as A common problem in some C programs is handling parameters passed as
@ -1154,18 +1134,17 @@ In Ruby:
<pre>r, c = Example.get_dimensions(m)<br></pre> <pre>r, c = Example.get_dimensions(m)<br></pre>
</blockquote> </blockquote>
<hr> <hr>
<a name="n28"></a> <H2><a name="Ruby_nn28"></a>26.5 Simple exception handling </H2>
<a name="n28"></a><H2>23.5 Simple exception handling </H2>
The SWIG <tt>%exception</tt> directive can be used to define a The SWIG <tt>%exception</tt> directive can be used to define a
user-definable user-definable
exception handler that can convert C/C++ errors into Ruby exceptions. exception handler that can convert C/C++ errors into Ruby exceptions.
The The
chapter on <a href="Customization.html">Customization Features</a> chapter on <a href="Customization.html#Customization">Customization Features</a>
contains more contains more
details, but suppose you have a C++ class like the following : details, but suppose you have a C++ class like the following :
<p></p>
<blockquote> <blockquote>
<pre>class DoubleArray {<br> private:<br> int n;<br> double *ptr;<br> public:<br> // Create a new array of fixed size<br> DoubleArray(int size) {<br> ptr = new double[size];<br> n = size;<br> }<br> // Destroy an array<br> ~DoubleArray() {<br> delete ptr;<br> }<br> // Return the length of the array<br> int length() {<br> return n;<br> }<br><br> // Get an array item and perform bounds checking.<br> double getitem(int i) {<br> if ((i &gt;= 0) &amp;&amp; (i &lt; n))<br> return ptr[i];<br> else<br> throw RangeError();<br> }<br> // Set an array item and perform bounds checking.<br> void setitem(int i, double val) {<br> if ((i &gt;= 0) &amp;&amp; (i &lt; n))<br> ptr[i] = val;<br> else {<br> throw RangeError();<br> }<br> }<br> };<br></pre> <pre>class DoubleArray {<br> private:<br> int n;<br> double *ptr;<br> public:<br> // Create a new array of fixed size<br> DoubleArray(int size) {<br> ptr = new double[size];<br> n = size;<br> }<br> // Destroy an array<br> ~DoubleArray() {<br> delete ptr;<br> }<br> // Return the length of the array<br> int length() {<br> return n;<br> }<br><br> // Get an array item and perform bounds checking.<br> double getitem(int i) {<br> if ((i &gt;= 0) &amp;&amp; (i &lt; n))<br> return ptr[i];<br> else<br> throw RangeError();<br> }<br> // Set an array item and perform bounds checking.<br> void setitem(int i, double val) {<br> if ((i &gt;= 0) &amp;&amp; (i &lt; n))<br> ptr[i] = val;<br> else {<br> throw RangeError();<br> }<br> }<br> };<br></pre>
</blockquote> </blockquote>
@ -1174,7 +1153,7 @@ out-of-bounds
access, you might want to catch this in the Ruby extension by writing access, you might want to catch this in the Ruby extension by writing
the the
following in an interface file: following in an interface file:
<p></p>
<blockquote> <blockquote>
<pre>%exception {<br> try {<br> $action<br> }<br> catch (const RangeError&amp;) {<br> static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);<br> rb_raise(cpperror, "Range error.");<br> }<br>}<br><br>class DoubleArray {<br> ...<br>};<br></pre> <pre>%exception {<br> try {<br> $action<br> }<br> catch (const RangeError&amp;) {<br> static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);<br> rb_raise(cpperror, "Range error.");<br> }<br>}<br><br>class DoubleArray {<br> ...<br>};<br></pre>
</blockquote> </blockquote>
@ -1196,7 +1175,7 @@ functions
named <tt>getitem</tt> and <tt>setitem</tt>. named <tt>getitem</tt> and <tt>setitem</tt>.
<p>Since SWIG's exception handling is user-definable, you are not <p>Since SWIG's exception handling is user-definable, you are not
limited to C++ limited to C++
exception handling. See the chapter on <a href="Customization.html">Customization exception handling. See the chapter on <a href="Customization.html#Customization">Customization
Features</a> for more examples. Features</a> for more examples.
</p> </p>
<p>When raising a Ruby exception from C/C++, use the <tt>rb_raise()</tt> <p>When raising a Ruby exception from C/C++, use the <tt>rb_raise()</tt>
@ -1210,7 +1189,7 @@ Ruby exception classes, consult a Ruby reference such as <a
href="http://www.rubycentral.com/book"><em>Programming Ruby</em></a>. href="http://www.rubycentral.com/book"><em>Programming Ruby</em></a>.
</p> </p>
<hr><a name="n29"></a> <hr><a name="n29"></a>
<a name="n29"></a><H2>23.6 Typemaps</H2> <H2><a name="Ruby_nn29"></a>26.6 Typemaps</H2>
This section describes how you can modify SWIG's default wrapping This section describes how you can modify SWIG's default wrapping
@ -1219,22 +1198,22 @@ for various C/C++ datatypes using the <tt>%typemap</tt> directive.
This This
is an advanced topic that assumes familiarity with the Ruby C API as is an advanced topic that assumes familiarity with the Ruby C API as
well well
as the material in the "<a href="Typemaps.html">Typemaps</a>" chapter. as the material in the "<a href="Typemaps.html#Typemaps">Typemaps</a>" chapter.
<p>Before proceeding, it should be stressed that typemaps are not a <p>Before proceeding, it should be stressed that typemaps are not a
required part of using SWIG---the default wrapping behavior is enough required part of using SWIG---the default wrapping behavior is enough
in most cases. in most cases.
Typemaps are only used if you want to change some aspect of the Typemaps are only used if you want to change some aspect of the
primitive primitive
C-Ruby interface. C-Ruby interface.
<a name="n30"></a></p>
<a name="n30"></a><H3>23.6.1 What is a typemap?</H3> <H3><a name="Ruby_nn30"></a>26.6.1 What is a typemap?</H3>
A typemap is nothing more than a code generation rule that is attached A typemap is nothing more than a code generation rule that is attached
to a specific C datatype. For example, to convert integers from Ruby to to a specific C datatype. For example, to convert integers from Ruby to
C, C,
you might define a typemap like this: you might define a typemap like this:
<p></p>
<blockquote> <blockquote>
<pre>%module example<br><br>%typemap(in) int {<br> $1 = (int) NUM2INT($input);<br> printf("Received an integer : %d\n",$1);<br>}<br><br>extern int fact(int n);<br></pre> <pre>%module example<br><br>%typemap(in) int {<br> $1 = (int) NUM2INT($input);<br> printf("Received an integer : %d\n",$1);<br>}<br><br>extern int fact(int n);<br></pre>
</blockquote> </blockquote>
@ -1254,7 +1233,7 @@ The <tt>$input</tt> variable is the input Ruby object.
<p>When this example is compiled into a Ruby module, the following <p>When this example is compiled into a Ruby module, the following
sample code: sample code:
</p> </p>
<p></p>
<blockquote> <blockquote>
<pre>require 'example'<br><br>puts Example.fact(6)<br></pre> <pre>require 'example'<br><br>puts Example.fact(6)<br></pre>
</blockquote> </blockquote>
@ -1308,8 +1287,7 @@ follows (notice how the length parameter is omitted):
<blockquote> <blockquote>
<pre>puts Example.count('o','Hello World')<br>2<br></pre> <pre>puts Example.count('o','Hello World')<br>2<br></pre>
</blockquote> </blockquote>
<a name="n31"></a> <H3><a name="Ruby_nn31"></a>26.6.2 Ruby typemaps</H3>
<a name="n31"></a><H3>23.6.2 Ruby typemaps</H3>
The previous section illustrated an "in" typemap for converting Ruby The previous section illustrated an "in" typemap for converting Ruby
@ -1363,16 +1341,15 @@ Ruby module:
<blockquote>Initialize an argument to a value before any conversions <blockquote>Initialize an argument to a value before any conversions
occur. occur.
</blockquote> </blockquote>
Examples of these typemaps appears in the <a href="#n34">section on Examples of these typemaps appears in the <a href="#ruby_typemap_examples">section on
typemap typemap
examples</a> examples</a>
<a name="n32"></a> <H3><a name="Ruby_nn32"></a>26.6.3 Typemap variables</H3>
<a name="n32"></a><H3>23.6.3 Typemap variables</H3>
Within a typemap, a number of special variables prefaced with a <tt>$</tt> Within a typemap, a number of special variables prefaced with a <tt>$</tt>
may appear. A full list of variables can be found in the "<a may appear. A full list of variables can be found in the "<a
href="Typemaps.html">Typemaps</a>" chapter. This is a list of the most href="Typemaps.html#Typemaps">Typemaps</a>" chapter. This is a list of the most
common common
variables: variables:
<p><tt>$1</tt> <p><tt>$1</tt>
@ -1410,8 +1387,7 @@ so that their values can be properly assigned.
<tt>$symname</tt> <tt>$symname</tt>
<blockquote>The Ruby name of the wrapper function being created. <blockquote>The Ruby name of the wrapper function being created.
</blockquote> </blockquote>
<a name="n33"></a> <H3><a name="Ruby_nn33"></a>26.6.4 Useful Functions</H3>
<a name="n33"></a><H3>23.6.4 Useful Functions</H3>
When you write a typemap, you usually have to work directly with Ruby When you write a typemap, you usually have to work directly with Ruby
@ -1422,21 +1398,19 @@ more can be found in <a href="http://www.rubycentral.com/book"><em>Programming
Ruby</em></a>, by David Thomas Ruby</em></a>, by David Thomas
and Andrew Hunt.) and Andrew Hunt.)
<p><a name="n34"></a></p> <p><a name="n34"></a></p>
<a name="n34"></a><H4>23.6.4.1 C Datatypes to Ruby Objects</H4> <H4><a name="Ruby_nn34"></a>26.6.4.1 C Datatypes to Ruby Objects</H4>
<blockquote> <blockquote>
<pre>INT2NUM(long or int) - int to Fixnum or Bignum<br>INT2FIX(long or int) - int to Fixnum (faster than INT2NUM)<br>CHR2FIX(char) - char to Fixnum<br>rb_str_new2(char*) - char* to String<br>rb_float_new(double) - double to Float<br></pre> <pre>INT2NUM(long or int) - int to Fixnum or Bignum<br>INT2FIX(long or int) - int to Fixnum (faster than INT2NUM)<br>CHR2FIX(char) - char to Fixnum<br>rb_str_new2(char*) - char* to String<br>rb_float_new(double) - double to Float<br></pre>
</blockquote> </blockquote>
<a name="n35"></a> <H4><a name="Ruby_nn35"></a>26.6.4.2 Ruby Objects to C Datatypes</H4>
<a name="n35"></a><H4>23.6.4.2 Ruby Objects to C Datatypes</H4>
<blockquote> <blockquote>
<pre> int NUM2INT(Numeric)<br> int FIX2INT(Numeric)<br> unsigned int NUM2UINT(Numeric)<br> unsigned int FIX2UINT(Numeric)<br> long NUM2LONG(Numeric)<br> long FIX2LONG(Numeric)<br>unsigned long FIX2ULONG(Numeric)<br> char NUM2CHR(Numeric or String)<br> char * STR2CSTR(String)<br> char * rb_str2cstr(String, int*length)<br> double NUM2DBL(Numeric)<br><br></pre> <pre> int NUM2INT(Numeric)<br> int FIX2INT(Numeric)<br> unsigned int NUM2UINT(Numeric)<br> unsigned int FIX2UINT(Numeric)<br> long NUM2LONG(Numeric)<br> long FIX2LONG(Numeric)<br>unsigned long FIX2ULONG(Numeric)<br> char NUM2CHR(Numeric or String)<br> char * STR2CSTR(String)<br> char * rb_str2cstr(String, int*length)<br> double NUM2DBL(Numeric)<br><br></pre>
</blockquote> </blockquote>
<a name="n36"></a> <H4><a name="Ruby_nn36"></a>26.6.4.3 Macros for VALUE</H4>
<a name="n36"></a><H4>23.6.4.3 Macros for VALUE</H4>
<p> <p>
@ -1451,8 +1425,7 @@ and Andrew Hunt.)
<blockquote>capacity of the Ruby array</blockquote> <blockquote>capacity of the Ruby array</blockquote>
<tt>RARRAY(arr)-&gt;ptr</tt> <tt>RARRAY(arr)-&gt;ptr</tt>
<blockquote>pointer to array storage</blockquote> <blockquote>pointer to array storage</blockquote>
<a name="n37"></a> <H4><a name="Ruby_nn37"></a>26.6.4.4 Exceptions</H4>
<a name="n37"></a><H4>23.6.4.4 Exceptions</H4>
<p> <p>
@ -1510,8 +1483,7 @@ interpreted as with <tt>printf()</tt>.
if Ruby was invoked with the <tt>-w</tt> flag. The given format string if Ruby was invoked with the <tt>-w</tt> flag. The given format string
<i>fmt</i> and remaining arguments are interpreted as with <tt>printf()</tt>. <i>fmt</i> and remaining arguments are interpreted as with <tt>printf()</tt>.
</blockquote> </blockquote>
<a name="n38"></a> <H4><a name="Ruby_nn38"></a>26.6.4.5 Iterators</H4>
<a name="n38"></a><H4>23.6.4.5 Iterators</H4>
<p> <p>
@ -1544,15 +1516,13 @@ value)</tt>
<tt>void rb_throw(const char *tag, VALUE value)</tt> <tt>void rb_throw(const char *tag, VALUE value)</tt>
<blockquote> Equivalent to Ruby's <tt>throw</tt>. <blockquote> Equivalent to Ruby's <tt>throw</tt>.
</blockquote> </blockquote>
<a name="n39"></a> <H3><a name="ruby_typemap_examples"></a>26.6.5 Typemap Examples</H3>
<a name="n39"></a><H3>23.6.5 Typemap Examples</H3>
This section includes a few examples of typemaps. For more examples, This section includes a few examples of typemaps. For more examples,
you you
might look at the examples in the <tt>Example/ruby</tt> directory. might look at the examples in the <tt>Example/ruby</tt> directory.
<a name="n40"></a> <H3><a name="Ruby_nn40"></a>26.6.6 Converting a Ruby array to a char **</H3>
<a name="n40"></a><H3>23.6.6 Converting a Ruby array to a char **</H3>
A common problem in many C programs is the processing of command line A common problem in many C programs is the processing of command line
@ -1560,15 +1530,15 @@ arguments, which are usually passed in an array of <tt>NULL</tt>
terminated terminated
strings. The following SWIG interface file allows a Ruby Array instance strings. The following SWIG interface file allows a Ruby Array instance
to be used as a <tt>char **</tt> object. to be used as a <tt>char **</tt> object.
<p></p>
<p></p>
<blockquote> <blockquote>
<pre>%module argv<br><br>// This tells SWIG to treat char ** as a special case<br>%typemap(in) char ** {<br> /* Get the length of the array */<br> int size = RARRAY($input)-&gt;len; <br> int i;<br> $1 = (char **) malloc((size+1)*sizeof(char *));<br> /* Get the first element in memory */<br> VALUE *ptr = RARRAY($input)-&gt;ptr; <br> for (i=0; i &lt; size; i++, ptr++)<br> /* Convert Ruby Object String to char* */<br> $1[i]= STR2CSTR(*ptr); <br> $1[i]=NULL; /* End of list */<br>}<br><br>// This cleans up the char ** array created before <br>// the function call<br><br>%typemap(freearg) char ** {<br> free((char *) $1);<br>}<br><br>// Now a test function<br>%inline %{<br>int print_args(char **argv) {<br> int i = 0;<br> while (argv[i]) {<br> printf("argv[%d] = %s\n", i,argv[i]);<br> i++;<br> }<br> return i;<br>}<br>%}<br><br></pre> <pre>%module argv<br><br>// This tells SWIG to treat char ** as a special case<br>%typemap(in) char ** {<br> /* Get the length of the array */<br> int size = RARRAY($input)-&gt;len; <br> int i;<br> $1 = (char **) malloc((size+1)*sizeof(char *));<br> /* Get the first element in memory */<br> VALUE *ptr = RARRAY($input)-&gt;ptr; <br> for (i=0; i &lt; size; i++, ptr++)<br> /* Convert Ruby Object String to char* */<br> $1[i]= STR2CSTR(*ptr); <br> $1[i]=NULL; /* End of list */<br>}<br><br>// This cleans up the char ** array created before <br>// the function call<br><br>%typemap(freearg) char ** {<br> free((char *) $1);<br>}<br><br>// Now a test function<br>%inline %{<br>int print_args(char **argv) {<br> int i = 0;<br> while (argv[i]) {<br> printf("argv[%d] = %s\n", i,argv[i]);<br> i++;<br> }<br> return i;<br>}<br>%}<br><br></pre>
</blockquote> </blockquote>
When this module is compiled, the wrapped C function now operates as When this module is compiled, the wrapped C function now operates as
follows : follows :
<p></p>
<p></p>
<blockquote> <blockquote>
<pre>require 'Argv'<br>Argv.print_args(["Dave","Mike","Mary","Jane","John"])<br>argv[0] = Dave<br>argv[1] = Mike<br>argv[2] = Mary<br>argv[3] = Jane<br>argv[4] = John<br></pre> <pre>require 'Argv'<br>Argv.print_args(["Dave","Mike","Mary","Jane","John"])<br>argv[0] = Dave<br>argv[1] = Mike<br>argv[2] = Mary<br>argv[3] = Jane<br>argv[4] = John<br></pre>
</blockquote> </blockquote>
@ -1580,7 +1550,7 @@ allocation is used to allocate memory for the array, the "freearg"
typemap is typemap is
used to later release this memory after the execution of the C used to later release this memory after the execution of the C
function. <a name="n41"></a> function. <a name="n41"></a>
<a name="n41"></a><H3>23.6.7 Collecting arguments in a hash</H3> <H3><a name="Ruby_nn41"></a>26.6.7 Collecting arguments in a hash</H3>
Ruby's solution to the "keyword arguments" capability of some other Ruby's solution to the "keyword arguments" capability of some other
@ -1736,8 +1706,7 @@ uses
the extension, can be found in the <tt>Examples/ruby/hashargs</tt> the extension, can be found in the <tt>Examples/ruby/hashargs</tt>
directory directory
of the SWIG distribution. of the SWIG distribution.
<a name="n42"></a> <H3><a name="Ruby_nn42"></a>26.6.8 Pointer handling</H3>
<a name="n42"></a><H3>23.6.8 Pointer handling</H3>
Occasionally, it might be necessary to convert pointer values that have Occasionally, it might be necessary to convert pointer values that have
@ -1797,8 +1766,7 @@ typemap variable <tt>$1_descriptor</tt>. For example:
<blockquote> <blockquote>
<pre>%typemap(in) Foo * {<br> SWIG_ConvertPtr($input, (void **) &amp;$1, $1_descriptor, 1);<br>}<br></pre> <pre>%typemap(in) Foo * {<br> SWIG_ConvertPtr($input, (void **) &amp;$1, $1_descriptor, 1);<br>}<br></pre>
</blockquote> </blockquote>
<a name="n43"></a> <H4><a name="Ruby_nn43"></a>26.6.8.1 Ruby Datatype Wrapping</H4>
<a name="n43"></a><H4>23.6.8.1 Ruby Datatype Wrapping</H4>
<p> <p>
@ -1822,8 +1790,7 @@ from the data object
<i>obj</i> and assigns that pointer to <i>ptr</i>. <i>obj</i> and assigns that pointer to <i>ptr</i>.
</blockquote> </blockquote>
<hr> <hr>
<a name="n44"></a> <H2><a name="ruby_operator_overloading"></a>26.7 Operator overloading</H2>
<a name="n44"></a><H2>23.7 Operator overloading</H2>
SWIG allows operator overloading with, by using the <tt>%extend</tt> SWIG allows operator overloading with, by using the <tt>%extend</tt>
@ -1838,8 +1805,7 @@ Note that although SWIG supports the <tt>__eq__</tt> magic method name
for defining an equivalence operator, there is no separate method for for defining an equivalence operator, there is no separate method for
handling <i>inequality</i> since Ruby parses the expression <i>a != b</i> handling <i>inequality</i> since Ruby parses the expression <i>a != b</i>
as <i>!(a == b)</i>. as <i>!(a == b)</i>.
<a name="n45"></a> <H3><a name="Ruby_nn45"></a>26.7.1 Example: STL Vector to Ruby Array</H3>
<a name="n45"></a><H3>23.7.1 Example: STL Vector to Ruby Array</H3>
<em><b>FIXME: This example is out of place here!</b></em> <em><b>FIXME: This example is out of place here!</b></em>
@ -1855,7 +1821,7 @@ construct this type of macro/typemap and should give insight into
constructing constructing
similar typemaps for other STL structures: similar typemaps for other STL structures:
</p> </p>
<p></p>
<blockquote> <blockquote>
<pre>%define PTR_VECTOR_TO_RUBY_ARRAY(vectorclassname, classname)<br>%typemap(ruby, out) vectorclassname &amp;, const vectorclassname &amp; {<br> VALUE arr = rb_ary_new2($1-&gt;size());<br> vectorclassname::iterator i = $1-&gt;begin(), iend = $1-&gt;end();<br> for ( ; i!=iend; i++ )<br> rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i));<br> $result = arr;<br>}<br>%typemap(ruby, out) vectorclassname, const vectorclassname {<br> VALUE arr = rb_ary_new2($1.size());<br> vectorclassname::iterator i = $1.begin(), iend = $1.end();<br> for ( ; i!=iend; i++ )<br> rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i));<br> $result = arr;<br>}<br>%enddef<br></pre> <pre>%define PTR_VECTOR_TO_RUBY_ARRAY(vectorclassname, classname)<br>%typemap(ruby, out) vectorclassname &amp;, const vectorclassname &amp; {<br> VALUE arr = rb_ary_new2($1-&gt;size());<br> vectorclassname::iterator i = $1-&gt;begin(), iend = $1-&gt;end();<br> for ( ; i!=iend; i++ )<br> rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i));<br> $result = arr;<br>}<br>%typemap(ruby, out) vectorclassname, const vectorclassname {<br> VALUE arr = rb_ary_new2($1.size());<br> vectorclassname::iterator i = $1.begin(), iend = $1.end();<br> for ( ; i!=iend; i++ )<br> rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i));<br> $result = arr;<br>}<br>%enddef<br></pre>
</blockquote> </blockquote>
@ -1864,19 +1830,20 @@ preprocessor step
to determine the actual object from the class name. to determine the actual object from the class name.
<p>To use the macro with a class Foo, the following is used: <p>To use the macro with a class Foo, the following is used:
</p> </p>
<p></p>
<blockquote> <blockquote>
<pre>PTR_VECTOR_TO_RUBY_ARRAY(vector<foo *="">, Foo)<br></foo></pre> <pre>PTR_VECTOR_TO_RUBY_ARRAY(vector&lt;foo *=""&gt;, Foo)<br></pre>
</blockquote> </blockquote>
It is also possible to create a STL vector of Ruby objects: It is also possible to create a STL vector of Ruby objects:
<p></p>
<blockquote> <blockquote>
<pre>%define RUBY_ARRAY_TO_PTR_VECTOR(vectorclassname, classname)<br>%typemap(ruby, in) vectorclassname &amp;, const vectorclassname &amp; {<br> Check_Type($input, T_ARRAY);<br> vectorclassname *vec = new vectorclassname;<br> int len = RARRAY($input)-&gt;len;<br> for (int i=0; i!=len; i++) {<br> VALUE inst = rb_ary_entry($input, i);<br> //The following _should_ work but doesn't on HPUX<br> // Check_Type(inst, T_DATA);<br> classname *element = NULL;<br> Data_Get_Struct(inst, classname, element);<br> vec-&gt;push_back(element);<br> }<br> $1 = vec;<br>}<br><br>%typemap(ruby, freearg) vectorclassname &amp;, const vectorclassname &amp; {<br> delete $1;<br>}<br>%enddef<br></pre> <pre>%define RUBY_ARRAY_TO_PTR_VECTOR(vectorclassname, classname)<br>%typemap(ruby, in) vectorclassname &amp;, const vectorclassname &amp; {<br> Check_Type($input, T_ARRAY);<br> vectorclassname *vec = new vectorclassname;<br> int len = RARRAY($input)-&gt;len;<br> for (int i=0; i!=len; i++) {<br> VALUE inst = rb_ary_entry($input, i);<br> //The following _should_ work but doesn't on HPUX<br> // Check_Type(inst, T_DATA);<br> classname *element = NULL;<br> Data_Get_Struct(inst, classname, element);<br> vec-&gt;push_back(element);<br> }<br> $1 = vec;<br>}<br><br>%typemap(ruby, freearg) vectorclassname &amp;, const vectorclassname &amp; {<br> delete $1;<br>}<br>%enddef<br></pre>
</blockquote> </blockquote>
It is also possible to create a Ruby array from a vector of static data It is also possible to create a Ruby array from a vector of static data
types: types:
<p></p>
<pre><blockquote> <blockquote><pre>
%define VECTOR_TO_RUBY_ARRAY(vectorclassname, classname) %define VECTOR_TO_RUBY_ARRAY(vectorclassname, classname)
%typemap(ruby, out) vectorclassname &amp;, const vectorclassname &amp; { %typemap(ruby, out) vectorclassname &amp;, const vectorclassname &amp; {
VALUE arr = rb_ary_new2($1-&gt;size()); VALUE arr = rb_ary_new2($1-&gt;size());
@ -1893,16 +1860,14 @@ types:
$result = arr; $result = arr;
} }
%enddef %enddef
</blockquote></pre> </pre></blockquote>
<a name="n46"></a> <H2><a name="Ruby_nn46"></a>26.8 Advanced Topics</H2>
<a name="n46"></a><H2>23.8 Advanced Topics</H2>
<a name="n47"></a> <H3><a name="Ruby_nn47"></a>26.8.1 Creating Multi-Module Packages</H3>
<a name="n47"></a><H3>23.8.1 Creating Multi-Module Packages</H3>
The chapter on <a href="Advanced.html">Advanced Topics</a> discusses The chapter on <a href="Advanced.html#Advanced">Advanced Topics</a> discusses
the basics the basics
of creating multi-module extensions with SWIG, and in particular of creating multi-module extensions with SWIG, and in particular
the considerations for sharing runtime type information among the the considerations for sharing runtime type information among the
@ -1924,7 +1889,7 @@ option so that
the runtime library code is omitted from the wrapper files. We'll start the runtime library code is omitted from the wrapper files. We'll start
by building by building
the <b>Shape</b> extension module: the <b>Shape</b> extension module:
<p></p>
<blockquote> <blockquote>
<pre>$ <b>swig -c++ -ruby -c shape.i</b> <pre>$ <b>swig -c++ -ruby -c shape.i</b>
</pre> </pre>
@ -1933,14 +1898,14 @@ SWIG generates a wrapper file named <tt>shape_wrap.cxx</tt>. To
compile this compile this
into a dynamically loadable extension for Ruby, prepare an <tt>extconf.rb</tt> into a dynamically loadable extension for Ruby, prepare an <tt>extconf.rb</tt>
script using this template: script using this template:
<p></p>
<blockquote> <blockquote>
<pre>require 'mkmf'<br><br># Since the SWIG runtime support library for Ruby (libswigrb.so)<br># depends on the Ruby library, make sure it's in the list<br># of libraries.<br>$libs = append_library($libs, Config::CONFIG['RUBY_INSTALL_NAME'])<br><br># Now add the SWIG runtime support library<br>have_library('swigrb', 'SWIG_InitRuntime')<br><br># Create the makefile<br>create_makefile('shape')<br></pre> <pre>require 'mkmf'<br><br># Since the SWIG runtime support library for Ruby (libswigrb.so)<br># depends on the Ruby library, make sure it's in the list<br># of libraries.<br>$libs = append_library($libs, Config::CONFIG['RUBY_INSTALL_NAME'])<br><br># Now add the SWIG runtime support library<br>have_library('swigrb', 'SWIG_InitRuntime')<br><br># Create the makefile<br>create_makefile('shape')<br></pre>
</blockquote> </blockquote>
Run this script to create a <tt>Makefile</tt> and then type <tt>make</tt> Run this script to create a <tt>Makefile</tt> and then type <tt>make</tt>
to to
build the shared library: build the shared library:
<p></p>
<blockquote> <blockquote>
<pre>$ <b>ruby extconf.rb</b> <pre>$ <b>ruby extconf.rb</b>
checking for SWIG_InitRuntime() in -lswigrb... yes checking for SWIG_InitRuntime() in -lswigrb... yes
@ -1974,7 +1939,7 @@ to create a platform-specific <tt>Makefile</tt> for the extension;
Once you've built both of these extension modules, you can test them Once you've built both of these extension modules, you can test them
interactively in IRB to confirm that the <tt>Shape</tt> and <tt>Circle</tt> interactively in IRB to confirm that the <tt>Shape</tt> and <tt>Circle</tt>
modules are properly loaded and initialized: modules are properly loaded and initialized:
<p></p>
<blockquote> <blockquote>
<pre>$ <b>irb</b> <pre>$ <b>irb</b>
irb(main):001:0&gt; <b>require 'shape'</b> irb(main):001:0&gt; <b>require 'shape'</b>
@ -1989,8 +1954,7 @@ irb(main):005:0&gt; <b>c.getX()</b>
5.0 5.0
</pre> </pre>
</blockquote> </blockquote>
<a name="n48"></a> <H3><a name="Ruby_nn48"></a>26.8.2 Defining Aliases</H3>
<a name="n48"></a><H3>23.8.2 Defining Aliases</H3>
It's a fairly common practice in the Ruby built-ins and standard It's a fairly common practice in the Ruby built-ins and standard
@ -2002,14 +1966,14 @@ one
of your class' instance methods, one approach is to use SWIG's of your class' instance methods, one approach is to use SWIG's
<tt>%extend</tt> directive to add a new method of the aliased name <tt>%extend</tt> directive to add a new method of the aliased name
that calls the original function. For example: that calls the original function. For example:
<p></p>
<blockquote> <blockquote>
<pre>class MyArray {<br>public:<br> // Construct an empty array<br> MyArray();<br> <br> // Return the size of this array<br> size_t length() const;<br>};<br><br>%extend MyArray {<br> // MyArray#size is an alias for MyArray#length<br> size_t size() const {<br> return self-&gt;length();<br> }<br>}<br></pre> <pre>class MyArray {<br>public:<br> // Construct an empty array<br> MyArray();<br> <br> // Return the size of this array<br> size_t length() const;<br>};<br><br>%extend MyArray {<br> // MyArray#size is an alias for MyArray#length<br> size_t size() const {<br> return self-&gt;length();<br> }<br>}<br></pre>
</blockquote> </blockquote>
A better solution is to instead use the <tt>%alias</tt> directive A better solution is to instead use the <tt>%alias</tt> directive
(unique to (unique to
SWIG's Ruby module). The previous example could then be rewritten as: SWIG's Ruby module). The previous example could then be rewritten as:
<p></p>
<blockquote> <blockquote>
<pre>// MyArray#size is an alias for MyArray#length<br>%alias MyArray::length "size";<br><br>class MyArray {<br>public:<br> // Construct an empty array<br> MyArray();<br> <br> // Return the size of this array<br> size_t length() const;<br>};<br></pre> <pre>// MyArray#size is an alias for MyArray#length<br>%alias MyArray::length "size";<br><br>class MyArray {<br>public:<br> // Construct an empty array<br> MyArray();<br> <br> // Return the size of this array<br> size_t length() const;<br>};<br></pre>
</blockquote> </blockquote>
@ -2032,11 +1996,11 @@ wrapper code that's usually associated with added methods like our
"features" "features"
mechanism and so the same name matching rules used for other kinds of mechanism and so the same name matching rules used for other kinds of
features features
apply (see the chapter on <a href="Customization.html">"Customization apply (see the chapter on <a href="Customization.html#Customization">"Customization
Features"</a>) Features"</a>)
for more details). for more details).
<a name="n49"></a></p>
<a name="n49"></a><H3>23.8.3 Predicate Methods</H3> <H3><a name="Ruby_nn49"></a>26.8.3 Predicate Methods</H3>
Predicate methods in Ruby are those which return either <tt>true</tt> Predicate methods in Ruby are those which return either <tt>true</tt>
@ -2068,7 +2032,7 @@ A better solution is to instead use the <tt>%predicate</tt> directive
to SWIG's Ruby module) to designate certain methods as predicate to SWIG's Ruby module) to designate certain methods as predicate
methods. methods.
For the previous example, this would look like: For the previous example, this would look like:
<p></p>
<blockquote> <blockquote>
<pre>%predicate is_it_safe();<br><br>int is_it_safe();<br></pre> <pre>%predicate is_it_safe();<br><br>int is_it_safe();<br></pre>
</blockquote> </blockquote>
@ -2082,10 +2046,9 @@ Note that the <tt>%predicate</tt> directive is implemented using
SWIG's SWIG's
"features" mechanism and so the same name matching rules used for other "features" mechanism and so the same name matching rules used for other
kinds kinds
of features apply (see the chapter on <a href="Customization.html">"Customization of features apply (see the chapter on <a href="Customization.html#Customization">"Customization
Features"</a>) for more details). Features"</a>) for more details).
<a name="n50"></a> <H3><a name="Ruby_nn50"></a>26.8.4 Specifying Mixin Modules</H3>
<a name="n50"></a><H3>23.8.4 Specifying Mixin Modules</H3>
The Ruby language doesn't support multiple inheritance, but it does The Ruby language doesn't support multiple inheritance, but it does
@ -2095,14 +2058,14 @@ method.
For example, if you have a Ruby class that defines an <em>each</em> For example, if you have a Ruby class that defines an <em>each</em>
instance instance
method, e.g. method, e.g.
<p></p>
<blockquote> <blockquote>
<pre>class Set<br> def initialize<br> @members = []<br> end<br> <br> def each<br> @members.each { |m| yield m }<br> end<br>end<br></pre> <pre>class Set<br> def initialize<br> @members = []<br> end<br> <br> def each<br> @members.each { |m| yield m }<br> end<br>end<br></pre>
</blockquote> </blockquote>
then you can mix-in Ruby's <tt>Enumerable</tt> module to easily add a then you can mix-in Ruby's <tt>Enumerable</tt> module to easily add a
lot lot
of functionality to your class: of functionality to your class:
<p></p>
<blockquote> <blockquote>
<pre>class Set<br> <b>include Enumerable</b> <pre>class Set<br> <b>include Enumerable</b>
@ -2133,10 +2096,9 @@ module names to the <tt>%mixin</tt> directive, e.g.
Note that the <tt>%mixin</tt> directive is implemented using SWIG's Note that the <tt>%mixin</tt> directive is implemented using SWIG's
"features" mechanism and so the same name matching rules used for other "features" mechanism and so the same name matching rules used for other
kinds kinds
of features apply (see the chapter on <a href="Customization.html">"Customization of features apply (see the chapter on <a href="Customization.html#Customization">"Customization
Features"</a>) for more details). Features"</a>) for more details).
<a name="n51"></a> <H3><a name="Ruby_nn51"></a>26.8.5 Interacting with Ruby's Garbage Collector</H3>
<a name="n51"></a><H3>23.8.5 Interacting with Ruby's Garbage Collector</H3>
<b>This section is still unfinished!</b> <b>This section is still unfinished!</b>
@ -2163,8 +2125,8 @@ models
a zoo and the animals in the zoo: a zoo and the animals in the zoo:
</p> </p>
<blockquote> <blockquote>
<pre>%module zoo<br><br>%{<br>#include <string> <pre>%module zoo<br><br>%{<br>#include &lt;string&gt;
#include <vector> #include &lt;vector&gt;
#include "zoo.h" #include "zoo.h"
%} %}
@ -2185,8 +2147,7 @@ public:
class Zoo class Zoo
{ {
protected: protected:
std::vector<animal std::vector&lt;animal *=""&gt; animals;<br> <br>public:<br> // Construct an empty zoo<br> Zoo() {}<br> <br> // Add a new animal to the zoo<br> void addAnimal(Animal* animal) {<br> animals.push_back(animal); <br> }<br> <br> // Return the number of animals in the zoo<br> size_t getNumAnimals() const {<br> return animals.size(); <br> }<br> <br> // Return a pointer to the ith animal<br> Animal* getAnimal(size_t i) const {<br> return animals[i]; <br> }<br>};<br><br></pre>
*=""> animals;<br> <br>public:<br> // Construct an empty zoo<br> Zoo() {}<br> <br> // Add a new animal to the zoo<br> void addAnimal(Animal* animal) {<br> animals.push_back(animal); <br> }<br> <br> // Return the number of animals in the zoo<br> size_t getNumAnimals() const {<br> return animals.size(); <br> }<br> <br> // Return a pointer to the ith animal<br> Animal* getAnimal(size_t i) const {<br> return animals[i]; <br> }<br>};<br><br></animal></vector></string></pre>
</blockquote> </blockquote>
Basically, a <tt>Zoo</tt> is modeled as a "container" for animals. And Basically, a <tt>Zoo</tt> is modeled as a "container" for animals. And
we can we can
@ -2247,8 +2208,8 @@ of the
Ruby instances associated with those C++ <tt>Animal</tt> objects: Ruby instances associated with those C++ <tt>Animal</tt> objects:
</p> </p>
<blockquote> <blockquote>
<pre>void Zoo_markfunc(void *ptr)<br>{<br> Animal *cppAnimal;<br> VALUE rubyAnimal;<br> Zoo *zoo;<br> <br> zoo = static_cast<zoo <pre>void Zoo_markfunc(void *ptr)<br>{<br> Animal *cppAnimal;<br> VALUE rubyAnimal;<br> Zoo *zoo;<br> <br> zoo = static_cast&lt;zoo
*="">(ptr);<br> for (size_t i = 0; i &lt; zoo-&gt;getNumAnimals(); i++) {<br> cppAnimal = zoo-&gt;getAnimal(i);<br> rubyAnimal = SWIG_RubyInstanceFor(cppAnimal);<br> rb_gc_mark(rubyAnimal);<br> }<br>}<br></zoo></pre> *=""&gt;(ptr);<br> for (size_t i = 0; i &lt; zoo-&gt;getNumAnimals(); i++) {<br> cppAnimal = zoo-&gt;getAnimal(i);<br> rubyAnimal = SWIG_RubyInstanceFor(cppAnimal);<br> rb_gc_mark(rubyAnimal);<br> }<br>}<br></pre>
</blockquote> </blockquote>
<em>SWIG_RubyInstanceFor() is an imaginary function that takes a <em>SWIG_RubyInstanceFor() is an imaginary function that takes a
pointer pointer
@ -2269,7 +2230,7 @@ are
implemented using SWIG's' "features" mechanism and so the same name implemented using SWIG's' "features" mechanism and so the same name
matching matching
rules used for other kinds of features apply (see the chapter on rules used for other kinds of features apply (see the chapter on
<a href="Customization.html">"Customization Features"</a>) <a href="Customization.html#Customization">"Customization Features"</a>)
for more details). for more details).
<hr> <hr>
<address>SWIG 1.3 - Last Modified : $Date$</address> <address>SWIG 1.3 - Last Modified : $Date$</address>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -5,23 +5,23 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>3 Scripting Languages</H1> <H1><a name="Scripting"></a>4 Scripting Languages</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">The two language view of the world</a> <li><a href="#Scripting_nn2">The two language view of the world</a>
<li><a href="#n3">How does a scripting language talk to C?</a> <li><a href="#Scripting_nn3">How does a scripting language talk to C?</a>
<ul> <ul>
<li><a href="#n4">Wrapper functions</a> <li><a href="#Scripting_nn4">Wrapper functions</a>
<li><a href="#n5">Variable linking</a> <li><a href="#Scripting_nn5">Variable linking</a>
<li><a href="#n6">Constants</a> <li><a href="#Scripting_nn6">Constants</a>
<li><a href="#n7">Structures and classes</a> <li><a href="#Scripting_nn7">Structures and classes</a>
<li><a href="#n8">Shadow classes</a> <li><a href="#Scripting_nn8">Shadow classes</a>
</ul> </ul>
<li><a href="#n9">Building scripting language extensions</a> <li><a href="#Scripting_nn9">Building scripting language extensions</a>
<ul> <ul>
<li><a href="#n10">Shared libraries and dynamic loading</a> <li><a href="#Scripting_nn10">Shared libraries and dynamic loading</a>
<li><a href="#n11">Linking with shared libraries</a> <li><a href="#Scripting_nn11">Linking with shared libraries</a>
<li><a href="#n12">Static linking</a> <li><a href="#Scripting_nn12">Static linking</a>
</ul> </ul>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -32,16 +32,17 @@ This chapter provides a brief overview of scripting language extension
programming and the mechanisms by which scripting language interpreters programming and the mechanisms by which scripting language interpreters
access C and C++ code. access C and C++ code.
<a name="n2"></a><H2>3.1 The two language view of the world</H2> <H2><a name="Scripting_nn2"></a>4.1 The two language view of the world</H2>
<p>
When a scripting language is used to control a C program, the When a scripting language is used to control a C program, the
resulting system tends to look as follows: resulting system tends to look as follows:
</p>
<p><center><img src="ch2.1.png"></center><p> <center><img src="ch2.1.png" alt="Scripting language input - C/C++ functions output"></center>
<p>
<p>
<p>
In this programming model, the scripting language interpreter is used In this programming model, the scripting language interpreter is used
for high level control whereas the underlying functionality of the for high level control whereas the underlying functionality of the
C/C++ program is accessed through special scripting language C/C++ program is accessed through special scripting language
@ -52,6 +53,7 @@ If you have ever used a package such as MATLAB or IDL, it is a
very similar model--the interpreter executes user commands and very similar model--the interpreter executes user commands and
scripts. However, most of the underlying functionality is written in scripts. However, most of the underlying functionality is written in
a low-level language like C or Fortran. a low-level language like C or Fortran.
</p>
<p> <p>
The two-language model of computing is extremely powerful because it The two-language model of computing is extremely powerful because it
@ -59,9 +61,9 @@ exploits the strengths of each language. C/C++ can be used for maximal
performance and complicated systems programming tasks. Scripting performance and complicated systems programming tasks. Scripting
languages can be used for rapid prototyping, interactive debugging, languages can be used for rapid prototyping, interactive debugging,
scripting, and access to high-level data structures such associative scripting, and access to high-level data structures such associative
arrays. <p> arrays. </p>
<a name="n3"></a><H2>3.2 How does a scripting language talk to C?</H2> <H2><a name="Scripting_nn3"></a>4.2 How does a scripting language talk to C?</H2>
Scripting languages are built around a parser that knows how Scripting languages are built around a parser that knows how
@ -82,14 +84,16 @@ and the underlying C function. Then you need to give the interpreter
information about the wrapper by providing details about the name of the information about the wrapper by providing details about the name of the
function, arguments, and so forth. The next few sections illustrate function, arguments, and so forth. The next few sections illustrate
the process. the process.
</p>
<a name="n4"></a><H3>3.2.1 Wrapper functions</H3> <H3><a name="Scripting_nn4"></a>4.2.1 Wrapper functions</H3>
Suppose you have an ordinary C function like this :<p>
<p> <p>
<blockquote><pre>int fact(int n) { Suppose you have an ordinary C function like this :</p>
<blockquote><pre>
int fact(int n) {
if (n &lt;= 1) return 1; if (n &lt;= 1) return 1;
else return n*fact(n-1); else return n*fact(n-1);
} }
@ -99,18 +103,17 @@ Suppose you have an ordinary C function like this :<p>
In order to access this function from a scripting language, it is In order to access this function from a scripting language, it is
necessary to write a special "wrapper" function that serves as the necessary to write a special "wrapper" function that serves as the
glue between the scripting language and the underlying C function. A glue between the scripting language and the underlying C function. A
wrapper function must do three things :<p> wrapper function must do three things :</p>
<p>
<ul> <ul>
<li>Gather function arguments and make sure they are valid. <li>Gather function arguments and make sure they are valid.
<li>Call the C function. <li>Call the C function.
<li>Convert the return value into a form recognized by the scripting language. <li>Convert the return value into a form recognized by the scripting language.
</ul> </ul>
<p>
<p>
As an example, the Tcl wrapper function for the <tt>fact()</tt> As an example, the Tcl wrapper function for the <tt>fact()</tt>
function above example might look like the following : <p> function above example might look like the following : </p>
<blockquote><pre> <blockquote><pre>
int wrap_fact(ClientData clientData, Tcl_Interp *interp, int wrap_fact(ClientData clientData, Tcl_Interp *interp,
@ -129,14 +132,15 @@ int wrap_fact(ClientData clientData, Tcl_Interp *interp,
</pre></blockquote> </pre></blockquote>
<p>
Once you have created a wrapper function, the final step is to tell the Once you have created a wrapper function, the final step is to tell the
scripting language about the new function. This is usually done in an scripting language about the new function. This is usually done in an
initialization function called by the language when the module is initialization function called by the language when the module is
loaded. For example, adding the above function to the Tcl interpreter loaded. For example, adding the above function to the Tcl interpreter
requires code like the following :<p> requires code like the following :</p>
<p> <blockquote><pre>
<blockquote><pre>int Wrap_Init(Tcl_Interp *interp) { int Wrap_Init(Tcl_Interp *interp) {
Tcl_CreateCommand(interp, "fact", wrap_fact, (ClientData) NULL, Tcl_CreateCommand(interp, "fact", wrap_fact, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL); (Tcl_CmdDeleteProc *) NULL);
return TCL_OK; return TCL_OK;
@ -145,41 +149,42 @@ requires code like the following :<p>
<p> <p>
When executed, Tcl will now have a new command called "<tt>fact</tt>" When executed, Tcl will now have a new command called "<tt>fact</tt>"
that you can use like any other Tcl command.<p> that you can use like any other Tcl command.</p>
<p> <p>
Although the process of adding a new function to Tcl has been Although the process of adding a new function to Tcl has been
illustrated, the procedure is almost identical for Perl and illustrated, the procedure is almost identical for Perl and
Python. Both require special wrappers to be written and both need Python. Both require special wrappers to be written and both need
additional initialization code. Only the specific details are additional initialization code. Only the specific details are
different.<p> different.</p>
<a name="n5"></a><H3>3.2.2 Variable linking</H3> <H3><a name="Scripting_nn5"></a>4.2.2 Variable linking</H3>
<p>
Variable linking refers to the problem of mapping a Variable linking refers to the problem of mapping a
C/C++ global variable to a variable in the scripting C/C++ global variable to a variable in the scripting
language interpeter. For example, suppose you had the following language interpeter. For example, suppose you had the following
variable:<p> variable:</p>
<p>
<blockquote><pre>double Foo = 3.5; <blockquote><pre>
double Foo = 3.5;
</pre></blockquote> </pre></blockquote>
<p> <p>
It might be nice to access it from a script as follows (shown for Perl):<p> It might be nice to access it from a script as follows (shown for Perl):</p>
<p> <blockquote><pre>
<blockquote><pre>$a = $Foo * 2.3; # Evaluation $a = $Foo * 2.3; # Evaluation
$Foo = $a + 2.0; # Assignment $Foo = $a + 2.0; # Assignment
</pre></blockquote> </pre></blockquote>
<p> <p>
To provide such access, variables are commonly manipulated using a To provide such access, variables are commonly manipulated using a
pair of get/set functions. For example, whenever the value of a pair of get/set functions. For example, whenever the value of a
variable is read, a "get" function is invoked. Similarly, whenever variable is read, a "get" function is invoked. Similarly, whenever
the value of a variable is changed, a "set" function is called. the value of a variable is changed, a "set" function is called.
</p>
<p> <p>
In many languages, calls to the get/set functions can be attached to In many languages, calls to the get/set functions can be attached to
@ -187,14 +192,16 @@ evaluation and assignment operators. Therefore, evaluating a variable
such as <tt>$Foo</tt> might implicitly call the get function. Similarly, such as <tt>$Foo</tt> might implicitly call the get function. Similarly,
typing <tt>$Foo = 4</tt> would call the underlying set function to change typing <tt>$Foo = 4</tt> would call the underlying set function to change
the value. the value.
</p>
<a name="n6"></a><H3>3.2.3 Constants</H3> <H3><a name="Scripting_nn6"></a>4.2.3 Constants</H3>
In many cases, a C program or library may define a large collection of In many cases, a C program or library may define a large collection of
constants. For example: constants. For example:
<blockquote><pre>#define RED 0xff0000 <blockquote><pre>
#define RED 0xff0000
#define BLUE 0x0000ff #define BLUE 0x0000ff
#define GREEN 0x00ff00 #define GREEN 0x00ff00
</pre></blockquote> </pre></blockquote>
@ -205,7 +212,7 @@ language variables such as <tt>$RED</tt>, <tt>$BLUE</tt>, and
functions for creating variables so installing constants is usually functions for creating variables so installing constants is usually
a trivial exercise. a trivial exercise.
<a name="n7"></a><H3>3.2.4 Structures and classes</H3> <H3><a name="Scripting_nn7"></a>4.2.4 Structures and classes</H3>
Although scripting languages have no trouble accessing simple Although scripting languages have no trouble accessing simple
@ -220,19 +227,20 @@ does C++ inheritance mean in a Perl interface?
The most straightforward technique for handling structures is to The most straightforward technique for handling structures is to
implement a collection of accessor functions that hide the underlying implement a collection of accessor functions that hide the underlying
representation of a structure. For example, representation of a structure. For example,
</p>
<p> <blockquote><pre>
<blockquote><pre>struct Vector { struct Vector {
Vector(); Vector();
~Vector(); ~Vector();
double x,y,z; double x,y,z;
}; };
</pre></blockquote> </pre></blockquote>
can be transformed into the following set of functions :<p> can be transformed into the following set of functions :
<p> <blockquote><pre>
<blockquote><pre>Vector *new_Vector(); Vector *new_Vector();
void delete_Vector(Vector *v); void delete_Vector(Vector *v);
double Vector_x_get(Vector *v); double Vector_x_get(Vector *v);
double Vector_y_get(Vector *v); double Vector_y_get(Vector *v);
@ -245,29 +253,31 @@ void Vector_z_set(Vector *v, double z);
Now, from an interpreter these function might be used as follows: Now, from an interpreter these function might be used as follows:
<p> <blockquote><pre>
<blockquote><pre>% set v [new_Vector] % set v [new_Vector]
% Vector_x_set $v 3.5 % Vector_x_set $v 3.5
% Vector_y_get $v % Vector_y_get $v
% delete_Vector $v % delete_Vector $v
% ... % ...
</pre></blockquote> </pre></blockquote>
<p>
<p>
Since accessor functions provide a mechanism for accessing the Since accessor functions provide a mechanism for accessing the
internals of an object, the interpreter does not need to know anything internals of an object, the interpreter does not need to know anything
about the actual representation of a <tt>Vector</tt>. about the actual representation of a <tt>Vector</tt>.
</p>
<a name="n8"></a><H3>3.2.5 Shadow classes</H3> <H3><a name="Scripting_nn8"></a>4.2.5 Shadow classes</H3>
<p>
In certain cases, it is possible to use the low-level accessor functions In certain cases, it is possible to use the low-level accessor functions
to create something known as a "shadow" class. to create something known as a "shadow" class.
A "shadow class" is a special kind of object that gets created A "shadow class" is a special kind of object that gets created
in a scripting language to access a C/C++ class (or struct) in a way in a scripting language to access a C/C++ class (or struct) in a way
that looks like the original structure (that is, it "shadows" the real that looks like the original structure (that is, it "shadows" the real
C++ class). For example, if you C++ class). For example, if you
have the following C definition :<p> have the following C definition :</p>
<blockquote><pre> <blockquote><pre>
class Vector { class Vector {
@ -277,13 +287,14 @@ public:
double x,y,z; double x,y,z;
}; };
</pre></blockquote> </pre></blockquote>
<p>
<p>
A shadow classing mechanism would allow you to access the structure in A shadow classing mechanism would allow you to access the structure in
a more natural manner from the interpreter. For example, in Python, you might want to do this: a more natural manner from the interpreter. For example, in Python, you might want to do this:
</p>
<p> <blockquote><pre>
<blockquote><pre>&gt;&gt;&gt; v = Vector() &gt;&gt;&gt; v = Vector()
&gt;&gt;&gt; v.x = 3 &gt;&gt;&gt; v.x = 3
&gt;&gt;&gt; v.y = 4 &gt;&gt;&gt; v.y = 4
&gt;&gt;&gt; v.z = -13 &gt;&gt;&gt; v.z = -13
@ -292,7 +303,7 @@ a more natural manner from the interpreter. For example, in Python, you might wa
</pre></blockquote> </pre></blockquote>
<p> <p>
Similarly, in Perl5 you may want the interface to work like this:<p> Similarly, in Perl5 you may want the interface to work like this:</p>
<blockquote><pre> <blockquote><pre>
$v = new Vector; $v = new Vector;
@ -302,7 +313,7 @@ $v-&gt;{z} = -13;
</pre></blockquote> </pre></blockquote>
Finally, in Tcl :<p> Finally, in Tcl :
<blockquote><pre> <blockquote><pre>
Vector v Vector v
@ -310,14 +321,17 @@ v configure -x 3 -y 4 -z 13
</pre></blockquote> </pre></blockquote>
<p>
When shadow classes are used, two objects are at really work--one in When shadow classes are used, two objects are at really work--one in
the scripting language, and an underlying C/C++ object. Operations the scripting language, and an underlying C/C++ object. Operations
affect both objects equally and for all practical purposes, it appears affect both objects equally and for all practical purposes, it appears
as if you are simply manipulating a C/C++ object. as if you are simply manipulating a C/C++ object.
</p>
<a name="n9"></a><H2>3.3 Building scripting language extensions</H2> <H2><a name="Scripting_nn9"></a>4.3 Building scripting language extensions</H2>
<p>
The final step in using a scripting language with your C/C++ The final step in using a scripting language with your C/C++
application is adding your extensions to the scripting language application is adding your extensions to the scripting language
itself. There are two primary approaches for doing itself. There are two primary approaches for doing
@ -325,16 +339,18 @@ this. The preferred technique is to build a dynamically loadable
extension in the form a shared library. Alternatively, you can extension in the form a shared library. Alternatively, you can
recompile the scripting language interpreter with your extensions recompile the scripting language interpreter with your extensions
added to it. added to it.
</p>
<a name="n10"></a><H3>3.3.1 Shared libraries and dynamic loading</H3> <H3><a name="Scripting_nn10"></a>4.3.1 Shared libraries and dynamic loading</H3>
To create a shared library or DLL, you often need to look at the
manual pages for your compiler and linker. However, the procedure
for a few common machines is shown below:<p>
<p> <p>
<blockquote><pre># Build a shared library for Solaris To create a shared library or DLL, you often need to look at the
manual pages for your compiler and linker. However, the procedure
for a few common machines is shown below:</p>
<blockquote><pre>
# Build a shared library for Solaris
gcc -c example.c example_wrap.c -I/usr/local/include gcc -c example.c example_wrap.c -I/usr/local/include
ld -G example.o example_wrap.o -o example.so ld -G example.o example_wrap.o -o example.so
@ -348,12 +364,14 @@ ld -shared example.o example_wrap.o -o example.so
</pre></blockquote> </pre></blockquote>
<p>
To use your shared library, you simply use the corresponding command To use your shared library, you simply use the corresponding command
in the scripting language (load, import, use, etc...). This will in the scripting language (load, import, use, etc...). This will
import your module and allow you to start using it. For example: import your module and allow you to start using it. For example:
</p>
<p> <blockquote><pre>
<blockquote><pre>% load ./example.so % load ./example.so
% fact 4 % fact 4
24 24
% %
@ -364,24 +382,24 @@ When working with C++ codes, the process of building shared libraries
may be more complicated--primarily due to the fact that C++ modules may need may be more complicated--primarily due to the fact that C++ modules may need
additional code in order to operate correctly. On many machines, you additional code in order to operate correctly. On many machines, you
can build a shared C++ module by following the above procedures, but can build a shared C++ module by following the above procedures, but
changing the link line to the following :<p> changing the link line to the following :</p>
<p> <blockquote><pre>
<blockquote><pre>c++ -shared example.o example_wrap.o -o example.so c++ -shared example.o example_wrap.o -o example.so
</pre></blockquote> </pre></blockquote>
<H3><a name="Scripting_nn11"></a>4.3.2 Linking with shared libraries</H3>
<p> <p>
<a name="n11"></a><H3>3.3.2 Linking with shared libraries</H3>
When building extensions as shared libraries, it is not uncommon for When building extensions as shared libraries, it is not uncommon for
your extension to rely upon other shared libraries on your machine. In your extension to rely upon other shared libraries on your machine. In
order for the extension to work, it needs to be able to find all of order for the extension to work, it needs to be able to find all of
these libraries at run-time. Otherwise, you may get an error such as these libraries at run-time. Otherwise, you may get an error such as
the following :<p> the following :</p>
<p> <blockquote><pre>
<blockquote><pre>&gt;&gt;&gt; import graph &gt;&gt;&gt; import graph
Traceback (innermost last): Traceback (innermost last):
File "&lt;stdin&gt;", line 1, in ? File "&lt;stdin&gt;", line 1, in ?
File "/home/sci/data1/beazley/graph/graph.py", line 2, in ? File "/home/sci/data1/beazley/graph/graph.py", line 2, in ?
@ -396,8 +414,8 @@ lib/libgraph.so:/lib/cmplrs/cc/libgraph.so:/usr/lib/cmplrs/cc/libgraph.so:
What this error means is that the extension module created by SWIG What this error means is that the extension module created by SWIG
depends upon a shared library called "<tt>libgraph.so</tt>" that the depends upon a shared library called "<tt>libgraph.so</tt>" that the
system was unable to locate. To fix this problem, there are a few system was unable to locate. To fix this problem, there are a few
approaches you can take.<p> approaches you can take.</p>
<p>
<ul> <ul>
<li>Link your extension and explicitly tell the linker where the <li>Link your extension and explicitly tell the linker where the
required libraries are located. Often times, this can be done with a required libraries are located. Often times, this can be done with a
@ -417,23 +435,25 @@ the path using linker options instead.
</ul> </ul>
<a name="n12"></a><H3>3.3.3 Static linking</H3> <H3><a name="Scripting_nn12"></a>4.3.3 Static linking</H3>
<p>
With static linking, you rebuild the scripting language interpreter With static linking, you rebuild the scripting language interpreter
with extensions. The process usually involves compiling a short main with extensions. The process usually involves compiling a short main
program that adds your customized commands to the language and starts program that adds your customized commands to the language and starts
the interpreter. You then link your program with a library to produce the interpreter. You then link your program with a library to produce
a new scripting language executable. a new scripting language executable.
</p>
<p> <p>
Although static linking is supported on all platforms, this is not Although static linking is supported on all platforms, this is not
the preferred technique for building scripting language the preferred technique for building scripting language
extensions. In fact, there are very few practical reasons for doing this--consider extensions. In fact, there are very few practical reasons for doing this--consider
using shared libraries instead. using shared libraries instead.
</p>
<p><hr> <hr>
<address>SWIG 1.3 - Last Modified : July 16, 2001</address> <address>SWIG 1.3 - Last Modified : July 16, 2001</address>
</body> </body>
</html> </html>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -5,18 +5,18 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>11 Variable Length Arguments</H1> <H1><a name="Varargs"></a>13 Variable Length Arguments</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">Introduction</a> <li><a href="#Varargs_nn2">Introduction</a>
<li><a href="#n3">The Problem</a> <li><a href="#Varargs_nn3">The Problem</a>
<li><a href="#n4">Default varargs support</a> <li><a href="#Varargs_nn4">Default varargs support</a>
<li><a href="#n5">Argument replacement using %varargs</a> <li><a href="#Varargs_nn5">Argument replacement using %varargs</a>
<li><a href="#n6">Varargs and typemaps</a> <li><a href="#Varargs_nn6">Varargs and typemaps</a>
<li><a href="#n7">Varargs wrapping with libffi</a> <li><a href="#Varargs_nn7">Varargs wrapping with libffi</a>
<li><a href="#n8">Wrapping of va_list</a> <li><a href="#Varargs_nn8">Wrapping of va_list</a>
<li><a href="#n9">C++ Issues</a> <li><a href="#Varargs_nn9">C++ Issues</a>
<li><a href="#n10">Discussion</a> <li><a href="#Varargs_nn10">Discussion</a>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -25,18 +25,19 @@
<b>(a.k.a, "The horror. The horror.")</b> <b>(a.k.a, "The horror. The horror.")</b>
<p> <p>
This chapter describes the problem of wrapping functions that take a This chapter describes the problem of wrapping functions that take a
variable number of arguments. For instance, generating wrappers for variable number of arguments. For instance, generating wrappers for
the C <tt>printf()</tt> family of functions. the C <tt>printf()</tt> family of functions.
</p>
<p> <p>
This topic is sufficiently advanced to merit its own chapter. In This topic is sufficiently advanced to merit its own chapter. In
fact, support for varargs is an often requested feature that was first fact, support for varargs is an often requested feature that was first
added in SWIG-1.3.12. Most other wrapper generation tools have added in SWIG-1.3.12. Most other wrapper generation tools have
wisely chosen to avoid this issue. wisely chosen to avoid this issue.
</p>
<a name="n2"></a><H2>11.1 Introduction</H2> <H2><a name="Varargs_nn2"></a>13.1 Introduction</H2>
Some C and C++ programs may include functions that accept a variable Some C and C++ programs may include functions that accept a variable
@ -74,6 +75,7 @@ list of pointers into which return values are placed. However, variable
length arguments are also sometimes used to write functions that accept a length arguments are also sometimes used to write functions that accept a
NULL-terminated list of pointers. A good example of this would NULL-terminated list of pointers. A good example of this would
be a function like this: be a function like this:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -122,7 +124,7 @@ List make_list(const char *s, ...) {
</pre> </pre>
</blockquote> </blockquote>
<a name="n3"></a><H2>11.2 The Problem</H2> <H2><a name="Varargs_nn3"></a>13.2 The Problem</H2>
Generating wrappers for a variable length argument function presents a Generating wrappers for a variable length argument function presents a
@ -138,10 +140,12 @@ type <tt>va_list</tt>, this is something entirely different. You
can't take a <tt>va_list</tt> structure and pass it in place of the can't take a <tt>va_list</tt> structure and pass it in place of the
variable length arguments to another varargs function. It just variable length arguments to another varargs function. It just
doesn't work. doesn't work.
</p>
<p> <p>
The reason this doesn't work has to do with the way that function The reason this doesn't work has to do with the way that function
calls get compiled. For example, suppose that your program has a function call like this: calls get compiled. For example, suppose that your program has a function call like this:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -159,6 +163,7 @@ frame followed by a call to <tt>printf()</tt>.
<p> <p>
In contrast, suppose you attempted to make some kind of wrapper around In contrast, suppose you attempted to make some kind of wrapper around
<tt>printf()</tt> using code like this: <tt>printf()</tt> using code like this:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -188,6 +193,7 @@ worse, you won't know the types and sizes of arguments until run-time
as well. Needless to say, there is no obvious way to make the C as well. Needless to say, there is no obvious way to make the C
compiler generate code for a function call involving an unknown number compiler generate code for a function call involving an unknown number
of arguments of unknown types. of arguments of unknown types.
</p>
<p> <p>
In theory, it <em>is</em> possible to write a wrapper that does the right thing. In theory, it <em>is</em> possible to write a wrapper that does the right thing.
@ -195,6 +201,7 @@ However, this involves knowing the underlying ABI for the target platform and la
as well as writing special purpose code that manually constructed the call stack before as well as writing special purpose code that manually constructed the call stack before
making a procedure call. Unfortunately, both of these tasks require the use of inline making a procedure call. Unfortunately, both of these tasks require the use of inline
assembly code. Clearly, that's the kind of solution you would much rather avoid. assembly code. Clearly, that's the kind of solution you would much rather avoid.
</p>
<p> <p>
With this nastiness in mind, SWIG provides a number of solutions to the varargs With this nastiness in mind, SWIG provides a number of solutions to the varargs
@ -202,8 +209,9 @@ wrapping problem. Most of these solutions are compromises that provide limited
varargs support without having to resort to assembly language. However, SWIG varargs support without having to resort to assembly language. However, SWIG
can also support real varargs wrapping (with stack-frame manipulation) if you can also support real varargs wrapping (with stack-frame manipulation) if you
are willing to get hands dirty. Keep reading. are willing to get hands dirty. Keep reading.
</p>
<a name="n4"></a><H2>11.3 Default varargs support</H2> <H2><a name="Varargs_nn4"></a>13.3 Default varargs support</H2>
When variable length arguments appear in an interface, the default When variable length arguments appear in an interface, the default
@ -239,14 +247,14 @@ instance, you could make function calls like this (in Python):
<blockquote> <blockquote>
<pre> <pre>
>>> traceprintf("Hello World") &gt;&gt;&gt; traceprintf("Hello World")
>>> traceprintf("Hello %s. Your number is %d\n" % (name, num)) &gt;&gt;&gt; traceprintf("Hello %s. Your number is %d\n" % (name, num))
</pre> </pre>
</blockquote> </blockquote>
Notice how string formatting is being done in Python instead of C. Notice how string formatting is being done in Python instead of C.
<a name="n5"></a><H2>11.4 Argument replacement using %varargs</H2> <H2><a name="Varargs_nn5"></a>13.4 Argument replacement using %varargs</H2>
Instead of dropping the variable length arguments, an alternative approach is to replace Instead of dropping the variable length arguments, an alternative approach is to replace
@ -292,13 +300,15 @@ known. When replicated argument replacement is used, at least one extra
argument is added to the end of the arguments when making the function call. argument is added to the end of the arguments when making the function call.
This argument serves as a sentinel to make sure the list is properly terminated. This argument serves as a sentinel to make sure the list is properly terminated.
It has the same value as that supplied to the <tt>%varargs</tt> directive. It has the same value as that supplied to the <tt>%varargs</tt> directive.
</p>
<p> <p>
Argument replacement is not as useful when working with functions that accept Argument replacement is not as useful when working with functions that accept
mixed argument types such as <tt>printf()</tt>. Providing general purpose mixed argument types such as <tt>printf()</tt>. Providing general purpose
wrappers to such functions presents special problems (covered shortly). wrappers to such functions presents special problems (covered shortly).
</p>
<a name="n6"></a><H2>11.5 Varargs and typemaps</H2> <H2><a name="Varargs_nn6"></a>13.5 Varargs and typemaps</H2>
Variable length arguments may be used in typemap specifications. For example: Variable length arguments may be used in typemap specifications. For example:
@ -326,6 +336,7 @@ default behavior of SWIG is to pass the <tt>void *</tt> value as an argument to
the function. Therefore, you could use the pointer to hold a valid argument value if you wanted. the function. Therefore, you could use the pointer to hold a valid argument value if you wanted.
<p> <p>
To illustrate, here is a safer version of wrapping <tt>printf()</tt> in Python: To illustrate, here is a safer version of wrapping <tt>printf()</tt> in Python:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -369,6 +380,7 @@ The next example illustrates a more advanced kind of varargs typemap.
Disclaimer: this requires special support in the target language module and is not Disclaimer: this requires special support in the target language module and is not
guaranteed to work with all SWIG modules at this time. It also starts to illustrate guaranteed to work with all SWIG modules at this time. It also starts to illustrate
some of the more fundamental problems with supporting varargs in more generality. some of the more fundamental problems with supporting varargs in more generality.
</p>
<p> <p>
If a typemap is defined for any form of <tt>(...)</tt>, many SWIG If a typemap is defined for any form of <tt>(...)</tt>, many SWIG
@ -380,6 +392,7 @@ However, suppose that you wanted to create a Python wrapper for the
<tt>execlp()</tt> function shown earlier. To do this using a typemap <tt>execlp()</tt> function shown earlier. To do this using a typemap
instead of using <tt>%varargs</tt>, you might first write a typemap instead of using <tt>%varargs</tt>, you might first write a typemap
like this: like this:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -388,7 +401,7 @@ like this:
int argc; int argc;
for (i = 0; i &lt; 10; i++) args[i] = 0; for (i = 0; i &lt; 10; i++) args[i] = 0;
argc = PyTuple_Size(varargs); argc = PyTuple_Size(varargs);
if (argc > 10) { if (argc &gt; 10) {
PyErr_SetString(PyExc_ValueError,"Too many arguments"); PyErr_SetString(PyExc_ValueError,"Too many arguments");
return NULL; return NULL;
} }
@ -427,15 +440,16 @@ this:
int execlp(const char *path, const char *arg, ...); int execlp(const char *path, const char *arg, ...);
</pre> </pre>
</blockquote> </blockquote>
<p>
<p>
This patches everything up and creates a function that more or less This patches everything up and creates a function that more or less
works. However, don't try explaining this to your coworkers unless works. However, don't try explaining this to your coworkers unless
you know for certain that they've had several cups of coffee. If you you know for certain that they've had several cups of coffee. If you
really want to elevate your guru status and increase your job really want to elevate your guru status and increase your job
security, continue to the next section. security, continue to the next section.
</p>
<a name="n7"></a><H2>11.6 Varargs wrapping with libffi</H2> <H2><a name="Varargs_nn7"></a>13.6 Varargs wrapping with libffi</H2>
All of the previous examples have relied on features of SWIG that are All of the previous examples have relied on features of SWIG that are
@ -446,7 +460,7 @@ with a fixed number of arguments of known types. In many cases, this
works perfectly fine. However, if you want more generality than this, works perfectly fine. However, if you want more generality than this,
you need to bring out some bigger guns. you need to bring out some bigger guns.
<P> <p>
One way to do this is to use a special purpose library such as libffi One way to do this is to use a special purpose library such as libffi
(<a (<a
href="http://sources.redhat.com/libffi/">http://sources.redhat.com/libffi</a>). href="http://sources.redhat.com/libffi/">http://sources.redhat.com/libffi</a>).
@ -454,12 +468,14 @@ libffi is a library that allows you to dynamically construct
call-stacks and invoke procedures in a relatively platform independent call-stacks and invoke procedures in a relatively platform independent
manner. Details about the library can be found in the libffi manner. Details about the library can be found in the libffi
distribution and are not repeated here. distribution and are not repeated here.
</p>
<p> <p>
To illustrate the use of libffi, suppose that you <em>really</em> wanted to create a To illustrate the use of libffi, suppose that you <em>really</em> wanted to create a
wrapper for <tt>execlp()</tt> that accepted <em>any</em> number of wrapper for <tt>execlp()</tt> that accepted <em>any</em> number of
arguments. To do this, you might make a few adjustments to the previous arguments. To do this, you might make a few adjustments to the previous
example. For example: example. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -501,21 +517,21 @@ example. For example:
args = (char **) arg3; args = (char **) arg3;
/* Set up path parameter */ /* Set up path parameter */
types[0] = &ffi_type_pointer; types[0] = &amp;ffi_type_pointer;
values[0] = &arg1; values[0] = &amp;arg1;
/* Set up first argument */ /* Set up first argument */
types[1] = &ffi_type_pointer; types[1] = &amp;ffi_type_pointer;
values[1] = &arg2; values[1] = &amp;arg2;
/* Set up rest of parameters */ /* Set up rest of parameters */
for (i = 0; i &lt;= vc; i++) { for (i = 0; i &lt;= vc; i++) {
types[2+i] = &ffi_type_pointer; types[2+i] = &amp;ffi_type_pointer;
values[2+i] = &args[i]; values[2+i] = &amp;args[i];
} }
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3, if (ffi_prep_cif(&amp;cif, FFI_DEFAULT_ABI, vc+3,
&ffi_type_uint, types) == FFI_OK) { &amp;ffi_type_uint, types) == FFI_OK) {
ffi_call(&cif, (void (*)()) execlp, &result, values); ffi_call(&amp;cif, (void (*)()) execlp, &amp;result, values);
} else { } else {
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
free(types); free(types);
@ -541,6 +557,7 @@ first place?!?" Obviously, those are questions you'll have to answer for yourse
<p> <p>
As a more extreme example of libffi, here is some code that attempts to wrap <tt>printf()</tt>, As a more extreme example of libffi, here is some code that attempts to wrap <tt>printf()</tt>,
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -604,32 +621,32 @@ As a more extreme example of libffi, here is some code that attempts to wrap <tt
args = (vtype *) arg2; args = (vtype *) arg2;
/* Set up fmt parameter */ /* Set up fmt parameter */
types[0] = &ffi_type_pointer; types[0] = &amp;ffi_type_pointer;
values[0] = &arg1; values[0] = &amp;arg1;
/* Set up rest of parameters */ /* Set up rest of parameters */
for (i = 0; i &lt; vc; i++) { for (i = 0; i &lt; vc; i++) {
switch(args[i].type) { switch(args[i].type) {
case VT_INT: case VT_INT:
types[1+i] = &ffi_type_uint; types[1+i] = &amp;ffi_type_uint;
values[1+i] = &args[i].val.ivalue; values[1+i] = &amp;args[i].val.ivalue;
break; break;
case VT_DOUBLE: case VT_DOUBLE:
types[1+i] = &ffi_type_double; types[1+i] = &amp;ffi_type_double;
values[1+i] = &args[i].val.dvalue; values[1+i] = &amp;args[i].val.dvalue;
break; break;
case VT_POINTER: case VT_POINTER:
types[1+i] = &ffi_type_pointer; types[1+i] = &amp;ffi_type_pointer;
values[1+i] = &args[i].val.pvalue; values[1+i] = &amp;args[i].val.pvalue;
break; break;
default: default:
abort(); /* Whoa! We're seriously hosed */ abort(); /* Whoa! We're seriously hosed */
break; break;
} }
} }
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1, if (ffi_prep_cif(&amp;cif, FFI_DEFAULT_ABI, vc+1,
&ffi_type_uint, types) == FFI_OK) { &amp;ffi_type_uint, types) == FFI_OK) {
ffi_call(&cif, (void (*)()) printf, &result, values); ffi_call(&amp;cif, (void (*)()) printf, &amp;result, values);
} else { } else {
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
free(types); free(types);
@ -651,10 +668,10 @@ Much to your amazement, it even seems to work if you try it:
<blockquote> <blockquote>
<pre> <pre>
>>> import example &gt;&gt;&gt; import example
>>> example.printf("Grade: %s %d/60 = %0.2f%%\n", "Dave", 47, 47.0*100/60) &gt;&gt;&gt; example.printf("Grade: %s %d/60 = %0.2f%%\n", "Dave", 47, 47.0*100/60)
Grade: Dave 47/60 = 78.33% Grade: Dave 47/60 = 78.33%
>>> &gt;&gt;&gt;
</pre> </pre>
</blockquote> </blockquote>
@ -662,7 +679,7 @@ Of course, there are still some limitations to consider:
<blockquote> <blockquote>
<pre> <pre>
>>> example.printf("la de da de da %s", 42) &gt;&gt;&gt; example.printf("la de da de da %s", 42)
Segmentation fault (core dumped) Segmentation fault (core dumped)
</pre> </pre>
</blockquote> </blockquote>
@ -674,7 +691,7 @@ module, we used the special <tt>varargs</tt> variable to get these arguments. M
provide an argument number for the first extra argument. This can be used to index into an array of passed arguments to get provide an argument number for the first extra argument. This can be used to index into an array of passed arguments to get
values. Please consult the chapter on each language module for more details. values. Please consult the chapter on each language module for more details.
<a name="n8"></a><H2>11.7 Wrapping of va_list</H2> <H2><a name="Varargs_nn8"></a>13.7 Wrapping of va_list</H2>
Closely related to variable length argument wrapping, you may encounter functions that accept a parameter Closely related to variable length argument wrapping, you may encounter functions that accept a parameter
@ -694,7 +711,7 @@ of a <tt>va_list</tt> structure are closely tied to the underlying
call-stack. It's not clear that exporting a <tt>va_list</tt> would call-stack. It's not clear that exporting a <tt>va_list</tt> would
have any use or that it would work at all. have any use or that it would work at all.
<a name="n9"></a><H2>11.8 C++ Issues</H2> <H2><a name="Varargs_nn9"></a>13.8 C++ Issues</H2>
Wrapping of C++ member functions that accept a variable number of Wrapping of C++ member functions that accept a variable number of
@ -735,17 +752,19 @@ invocation might require a table lookup to obtain the proper function address
(although you might be able to obtain an address by casting a bound (although you might be able to obtain an address by casting a bound
pointer to a pointer to function as described in the C++ ARM section pointer to a pointer to function as described in the C++ ARM section
18.3.4). 18.3.4).
</p>
<p> <p>
If you do decide to change the underlying action code, be aware that SWIG If you do decide to change the underlying action code, be aware that SWIG
always places the <tt>this</tt> pointer in <tt>arg1</tt>. Other arguments always places the <tt>this</tt> pointer in <tt>arg1</tt>. Other arguments
are placed in <tt>arg2</tt>, <tt>arg3</tt>, and so forth. For example: are placed in <tt>arg2</tt>, <tt>arg3</tt>, and so forth. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
%feature("action") Foo::bar { %feature("action") Foo::bar {
... ...
result = arg1->bar(arg2, arg3, etc.); result = arg1-&gt;bar(arg2, arg3, etc.);
... ...
} }
</pre> </pre>
@ -755,7 +774,7 @@ Given the potential to shoot yourself in the foot, it is probably easier to reco
design or to provide an alternative interface using a helper function than it is to create a design or to provide an alternative interface using a helper function than it is to create a
fully general wrapper to a varargs C++ member function. fully general wrapper to a varargs C++ member function.
<a name="n10"></a><H2>11.9 Discussion</H2> <H2><a name="Varargs_nn10"></a>13.9 Discussion</H2>
This chapter has provided a number of techniques that can be used to address the problem of variable length This chapter has provided a number of techniques that can be used to address the problem of variable length
@ -770,6 +789,7 @@ are a number of subtle aspects of the solution to consider--mostly concerning th
problem has been decomposed. First, the example is structured in a way that tries to maintain separation problem has been decomposed. First, the example is structured in a way that tries to maintain separation
between wrapper-specific information and the declaration of the function itself. The idea here is that between wrapper-specific information and the declaration of the function itself. The idea here is that
you might structure your interface like this: you might structure your interface like this:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -823,8 +843,9 @@ carefully read the section "A7.3.2 Function Calls" in Kernighan and
Ritchie and make sure you fully understand the parameter passing conventions used for varargs. Ritchie and make sure you fully understand the parameter passing conventions used for varargs.
Also, be aware of the platform dependencies and reliability issues that Also, be aware of the platform dependencies and reliability issues that
this will introduce. Good luck. this will introduce. Good luck.
</p>
<p><hr> <hr>
<address>SWIG 1.3 - Last Modified : March 24, 2002</address> <address>SWIG 1.3 - Last Modified : March 24, 2002</address>
</body> </body>

View file

@ -5,33 +5,33 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>12 Warning Messages</H1> <H1><a name="Warnings"></a>14 Warning Messages</H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">Introduction</a> <li><a href="#Warnings_nn2">Introduction</a>
<li><a href="#n3">Warning message suppression</a> <li><a href="#Warnings_nn3">Warning message suppression</a>
<li><a href="#n4">Enabling additional warnings</a> <li><a href="#Warnings_nn4">Enabling additional warnings</a>
<li><a href="#n5">Issuing a warning message</a> <li><a href="#Warnings_nn5">Issuing a warning message</a>
<li><a href="#n6">Commentary</a> <li><a href="#Warnings_nn6">Commentary</a>
<li><a href="#n7">Warnings as errors</a> <li><a href="#Warnings_nn7">Warnings as errors</a>
<li><a href="#n8">Message output format</a> <li><a href="#Warnings_nn8">Message output format</a>
<li><a href="#n9">Warning number reference</a> <li><a href="#Warnings_nn9">Warning number reference</a>
<ul> <ul>
<li><a href="#n10">Deprecated features (100-199)</a> <li><a href="#Warnings_nn10">Deprecated features (100-199)</a>
<li><a href="#n11">Preprocessor (200-299)</a> <li><a href="#Warnings_nn11">Preprocessor (200-299)</a>
<li><a href="#n12">C/C++ Parser (300-399)</a> <li><a href="#Warnings_nn12">C/C++ Parser (300-399)</a>
<li><a href="#n13">Types and typemaps (400-499) </a> <li><a href="#Warnings_nn13">Types and typemaps (400-499) </a>
<li><a href="#n14">Code generation (500-599)</a> <li><a href="#Warnings_nn14">Code generation (500-599)</a>
<li><a href="#n15">Language module specific (800-899) </a> <li><a href="#Warnings_nn15">Language module specific (800-899) </a>
<li><a href="#n16">User defined (900-999)</a> <li><a href="#Warnings_nn16">User defined (900-999)</a>
</ul> </ul>
<li><a href="#n17">History</a> <li><a href="#Warnings_nn17">History</a>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
<a name="n2"></a><H2>12.1 Introduction</H2> <H2><a name="Warnings_nn2"></a>14.1 Introduction</H2>
During compilation, SWIG may generate a variety of warning messages. For example: During compilation, SWIG may generate a variety of warning messages. For example:
@ -47,7 +47,7 @@ Typically, warning messages indicate non-fatal problems with the input
where the generated wrapper code will probably compile, but it may not where the generated wrapper code will probably compile, but it may not
work like you expect. work like you expect.
<a name="n3"></a><H2>12.2 Warning message suppression</H2> <H2><a name="Warnings_nn3"></a>14.2 Warning message suppression</H2>
All warning messages have a numeric code that is shown in the warning message itself. All warning messages have a numeric code that is shown in the warning message itself.
@ -125,7 +125,7 @@ There is no option to suppress all SWIG warning messages. The warning messages
for a reason---to tell you that something may be <em>broken</em> in for a reason---to tell you that something may be <em>broken</em> in
your interface. Ignore the warning messages at your own peril. your interface. Ignore the warning messages at your own peril.
<a name="n4"></a><H2>12.3 Enabling additional warnings</H2> <H2><a name="Warnings_nn4"></a>14.3 Enabling additional warnings</H2>
Some warning messages are disabled by default and are generated only Some warning messages are disabled by default and are generated only
@ -143,6 +143,7 @@ When <tt>-Wall</tt> is used, all other warning filters are disabled.
<p> <p>
To selectively turn on extra warning messages, you can use the directives and options in the To selectively turn on extra warning messages, you can use the directives and options in the
previous section--simply add a "+" to all warning numbers. For example: previous section--simply add a "+" to all warning numbers. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -169,7 +170,7 @@ or
Note: selective enabling of warnings with <tt>%warnfilter</tt> overrides any global settings you might have Note: selective enabling of warnings with <tt>%warnfilter</tt> overrides any global settings you might have
made using <tt>-w</tt> or <tt>#pragma</tt>. made using <tt>-w</tt> or <tt>#pragma</tt>.
<a name="n5"></a><H2>12.4 Issuing a warning message</H2> <H2><a name="Warnings_nn5"></a>14.4 Issuing a warning message</H2>
Warning messages can be issued from an interface file using a number of directives. The Warning messages can be issued from an interface file using a number of directives. The
@ -187,6 +188,7 @@ your own warnings, make sure you don't use numbers defined in the table at the e
<p> <p>
The <tt>%ignorewarn</tt> directive is the same as <tt>%ignore</tt> except that it issues a The <tt>%ignorewarn</tt> directive is the same as <tt>%ignore</tt> except that it issues a
warning message whenever a matching declaration is found. For example: warning message whenever a matching declaration is found. For example:
</p>
<blockquote> <blockquote>
<pre> <pre>
@ -207,7 +209,7 @@ Warning messages can be associated with typemaps using the
In this case, the warning message will be printed whenever the typemap is actually used. In this case, the warning message will be printed whenever the typemap is actually used.
<a name="n6"></a><H2>12.5 Commentary</H2> <H2><a name="Warnings_nn6"></a>14.5 Commentary</H2>
The ability to suppress warning messages is really only provided for The ability to suppress warning messages is really only provided for
@ -221,15 +223,16 @@ Certain types of SWIG problems are errors. These usually arise due to
parsing errors (bad syntax) or semantic problems for which there is parsing errors (bad syntax) or semantic problems for which there is
no obvious recovery. There is no mechanism for suppressing error no obvious recovery. There is no mechanism for suppressing error
messages. messages.
</p>
<a name="n7"></a><H2>12.6 Warnings as errors</H2> <H2><a name="Warnings_nn7"></a>14.6 Warnings as errors</H2>
Warnings can be handled as errors by using the <tt>-Werror</tt> command line Warnings can be handled as errors by using the <tt>-Werror</tt> command line
option. This will cause SWIG to exit with a non successful exit code if a option. This will cause SWIG to exit with a non successful exit code if a
warning is encountered. warning is encountered.
<a name="n8"></a><H2>12.7 Message output format</H2> <H2><a name="Warnings_nn8"></a>14.7 Message output format</H2>
The output format for both warnings and errors can be selected for The output format for both warnings and errors can be selected for
@ -246,10 +249,10 @@ $ swig -python -Fmicrosoft example.i
example.i(4): Syntax error in input. example.i(4): Syntax error in input.
</pre></blockquote> </pre></blockquote>
<a name="n9"></a><H2>12.8 Warning number reference</H2> <H2><a name="Warnings_nn9"></a>14.8 Warning number reference</H2>
<a name="n10"></a><H3>12.8.1 Deprecated features (100-199)</H3> <H3><a name="Warnings_nn10"></a>14.8.1 Deprecated features (100-199)</H3>
<ul> <ul>
@ -275,7 +278,7 @@ example.i(4): Syntax error in input.
<li>120. Deprecated command line option (-c). <li>120. Deprecated command line option (-c).
</ul> </ul>
<a name="n11"></a><H3>12.8.2 Preprocessor (200-299)</H3> <H3><a name="Warnings_nn11"></a>14.8.2 Preprocessor (200-299)</H3>
<ul> <ul>
@ -283,7 +286,7 @@ example.i(4): Syntax error in input.
<li>202. Could not evaluate 'expr'. <li>202. Could not evaluate 'expr'.
</ul> </ul>
<a name="n12"></a><H3>12.8.3 C/C++ Parser (300-399)</H3> <H3><a name="Warnings_nn12"></a>14.8.3 C/C++ Parser (300-399)</H3>
<ul> <ul>
@ -330,7 +333,7 @@ example.i(4): Syntax error in input.
<li>368. operator/= ignored. <li>368. operator/= ignored.
<li>369. operator%= ignored. <li>369. operator%= ignored.
<li>370. operator^= ignored. <li>370. operator^= ignored.
<li>371. operator&= ignored. <li>371. operator&amp;= ignored.
<li>372. operator|= ignored. <li>372. operator|= ignored.
<li>373. operator&lt;&lt; ignored. <li>373. operator&lt;&lt; ignored.
<li>374. operator&gt;&gt;ignored. <li>374. operator&gt;&gt;ignored.
@ -357,7 +360,7 @@ example.i(4): Syntax error in input.
<li>395. operator delete[] ignored. <li>395. operator delete[] ignored.
</ul> </ul>
<a name="n13"></a><H3>12.8.4 Types and typemaps (400-499) </H3> <H3><a name="Warnings_nn13"></a>14.8.4 Types and typemaps (400-499) </H3>
<ul> <ul>
@ -379,7 +382,7 @@ example.i(4): Syntax error in input.
<li>468. No 'throw' typemap defined for exception type 'type'. <li>468. No 'throw' typemap defined for exception type 'type'.
</ul> </ul>
<a name="n14"></a><H3>12.8.5 Code generation (500-599)</H3> <H3><a name="Warnings_nn14"></a>14.8.5 Code generation (500-599)</H3>
<ul> <ul>
@ -390,7 +393,7 @@ example.i(4): Syntax error in input.
<li>505. Variable length arguments discarded. <li>505. Variable length arguments discarded.
<li>506. Can't wrap varargs with keyword arguments enabled. <li>506. Can't wrap varargs with keyword arguments enabled.
<li>507. Adding native function <em>name</em> not supported (ignored). <li>507. Adding native function <em>name</em> not supported (ignored).
<li>508. Declaration of '<em>name</em>' shadows declaration accessible via operator->() at <em>file:line</em>. <li>508. Declaration of '<em>name</em>' shadows declaration accessible via operator-&gt;() at <em>file:line</em>.
<li>509. Overloaded <em>declaration</em> is shadowed by <em>declaration</em> at <em>file</em>:<em>line</em>. <li>509. Overloaded <em>declaration</em> is shadowed by <em>declaration</em> at <em>file</em>:<em>line</em>.
<li>510. Friend function '<em>name</em>' ignored. <li>510. Friend function '<em>name</em>' ignored.
<li>511. Can't use keyword arguments with overloaded functions. <li>511. Can't use keyword arguments with overloaded functions.
@ -401,7 +404,7 @@ example.i(4): Syntax error in input.
<li>516. Overloaded method <em>declaration</em> ignored. Method <em>declaration</em> at <em>file</em>:<em>line</em> used. <li>516. Overloaded method <em>declaration</em> ignored. Method <em>declaration</em> at <em>file</em>:<em>line</em> used.
</ul> </ul>
<a name="n15"></a><H3>12.8.6 Language module specific (800-899) </H3> <H3><a name="Warnings_nn15"></a>14.8.6 Language module specific (800-899) </H3>
<ul> <ul>
@ -440,17 +443,17 @@ example.i(4): Syntax error in input.
<li>842. Covariant return types not supported in C#. Proxy method will return <em>basetype</em> (C#). <li>842. Covariant return types not supported in C#. Proxy method will return <em>basetype</em> (C#).
</ul> </ul>
<a name="n16"></a><H3>12.8.7 User defined (900-999)</H3> <H3><a name="Warnings_nn16"></a>14.8.7 User defined (900-999)</H3>
These numbers can be used by your own application. These numbers can be used by your own application.
<a name="n17"></a><H2>12.9 History</H2> <H2><a name="Warnings_nn17"></a>14.9 History</H2>
The ability to control warning messages was first added to SWIG-1.3.12. The ability to control warning messages was first added to SWIG-1.3.12.
<p><hr> <hr>
<address>SWIG 1.3 - Last Modified : June 28, 2003</address> <address>SWIG 1.3 - Last Modified : June 28, 2003</address>
</body> </body>
</html> </html>

View file

@ -5,35 +5,35 @@
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<a name="n1"></a><H1>2 Getting started on Windows </H1> <H1><a name="Windows"></a>3 Getting started on Windows </H1>
<!-- INDEX --> <!-- INDEX -->
<ul> <ul>
<li><a href="#n2">Installation on Windows</a> <li><a href="#Windows_nn2">Installation on Windows</a>
<ul> <ul>
<li><a href="#n3">Windows Executable</a> <li><a href="#Windows_nn3">Windows Executable</a>
</ul> </ul>
<li><a href="#n4">SWIG Windows Examples</a> <li><a href="#examples">SWIG Windows Examples</a>
<ul> <ul>
<li><a href="#n5">Instructions for using the Examples with Visual Studio</a> <li><a href="#Windows_nn5">Instructions for using the Examples with Visual Studio</a>
<ul> <ul>
<li><a href="#n6">Python</a> <li><a href="#Windows_nn6">Python</a>
<li><a href="#n7">TCL</a> <li><a href="#Windows_nn7">TCL</a>
<li><a href="#n8">Perl</a> <li><a href="#Windows_nn8">Perl</a>
<li><a href="#n9">Java</a> <li><a href="#Windows_nn9">Java</a>
<li><a href="#n10">Ruby</a> <li><a href="#Windows_nn10">Ruby</a>
<li><a href="#n11">C#</a> <li><a href="#Windows_nn11">C#</a>
</ul> </ul>
<li><a href="#n12">Instructions for using the Examples with other compilers</a> <li><a href="#Windows_nn12">Instructions for using the Examples with other compilers</a>
</ul> </ul>
<li><a href="#n13">SWIG on Cygwin and MinGW</a> <li><a href="#Windows_nn13">SWIG on Cygwin and MinGW</a>
<ul> <ul>
<li><a href="#n14">Building swig.exe on Windows</a> <li><a href="#swig_exe">Building swig.exe on Windows</a>
<ul> <ul>
<li><a href="#n15">Building swig.exe using MinGW and MSYS</a> <li><a href="#Windows_nn15">Building swig.exe using MinGW and MSYS</a>
<li><a href="#n16">Building swig.exe using Cygwin</a> <li><a href="#Windows_nn16">Building swig.exe using Cygwin</a>
<li><a href="#n17">Building swig.exe alternatives</a> <li><a href="#Windows_nn17">Building swig.exe alternatives</a>
</ul> </ul>
<li><a href="#n18">Running the examples on Windows using Cygwin</a> <li><a href="#examples_cygwin">Running the examples on Windows using Cygwin</a>
</ul> </ul>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -45,7 +45,7 @@ Installing SWIG and running the examples is covered as well as building the SWIG
Usage within the Unix like environments MinGW and Cygwin is also detailed. Usage within the Unix like environments MinGW and Cygwin is also detailed.
<a name="n2"></a><H2>2.1 Installation on Windows</H2> <H2><a name="Windows_nn2"></a>3.1 Installation on Windows</H2>
SWIG does not come with the usual Windows type installation program, however it is quite easy to get started. The main steps are: SWIG does not come with the usual Windows type installation program, however it is quite easy to get started. The main steps are:
@ -54,16 +54,14 @@ SWIG does not come with the usual Windows type installation program, however it
<li>Set environment variables as described in the <a href="#examples">SWIG Windows Examples</a> section in order to run examples using Visual C++. <li>Set environment variables as described in the <a href="#examples">SWIG Windows Examples</a> section in order to run examples using Visual C++.
</ul> </ul>
<a name="n3"></a><H3>2.1.1 Windows Executable</H3> <H3><a name="Windows_nn3"></a>3.1.1 Windows Executable</H3>
The swigwin distribution contains the SWIG Windows executable, swig.exe, which will run on 32 bit versions of Windows, ie Windows 95/98/ME/NT/2000/XP. The swigwin distribution contains the SWIG Windows executable, swig.exe, which will run on 32 bit versions of Windows, ie Windows 95/98/ME/NT/2000/XP.
If you want to build your own swig.exe have a look at <a href="#swig_exe">Building swig.exe on Windows</a>. If you want to build your own swig.exe have a look at <a href="#swig_exe">Building swig.exe on Windows</a>.
<p>
<a name="examples"></a> <H2><a name="examples"></a>3.2 SWIG Windows Examples</H2>
<a name="n4"></a><H2>2.2 SWIG Windows Examples</H2>
Using Microsoft Visual C++ is the most common approach to compiling and linking SWIG's output. Using Microsoft Visual C++ is the most common approach to compiling and linking SWIG's output.
@ -77,7 +75,7 @@ Alternatively run the <a href="#examples_cygwin">examples using Cygwin</a>.
More information on each of the examples is available with the examples distributed with SWIG (Examples/index.html). More information on each of the examples is available with the examples distributed with SWIG (Examples/index.html).
<a name="n5"></a><H3>2.2.1 Instructions for using the Examples with Visual Studio</H3> <H3><a name="Windows_nn5"></a>3.2.1 Instructions for using the Examples with Visual Studio</H3>
Ensure the SWIG executable is as supplied in the SWIG root directory in order for the examples to work. Ensure the SWIG executable is as supplied in the SWIG root directory in order for the examples to work.
@ -92,7 +90,7 @@ They are usually set from the Control Panel and System properties, but this depe
If you don't want to use environment variables then change all occurences of the environment variables in the .dsp files with hard coded values. If you don't want to use environment variables then change all occurences of the environment variables in the .dsp files with hard coded values.
If you are interested in how the project files are set up there is explanatory information in some of the language module's documentation. If you are interested in how the project files are set up there is explanatory information in some of the language module's documentation.
<a name="n6"></a><H4>2.2.1.1 Python</H4> <H4><a name="Windows_nn6"></a>3.2.1.1 Python</H4>
<b><tt>PYTHON_INCLUDE</tt></b> : Set this to the directory that contains python.h<br> <b><tt>PYTHON_INCLUDE</tt></b> : Set this to the directory that contains python.h<br>
@ -103,7 +101,7 @@ PYTHON_INCLUDE: d:\python21\include<br>
PYTHON_LIB: d:\python21\libs\python21.lib<br> PYTHON_LIB: d:\python21\libs\python21.lib<br>
</tt> </tt>
<a name="n7"></a><H4>2.2.1.2 TCL</H4> <H4><a name="Windows_nn7"></a>3.2.1.2 TCL</H4>
<b><tt>TCL_INCLUDE</tt></b> : Set this to the directory containing tcl.h<br> <b><tt>TCL_INCLUDE</tt></b> : Set this to the directory containing tcl.h<br>
@ -114,7 +112,7 @@ TCL_INCLUDE: d:\tcl\include<br>
TCL_LIB: d:\tcl\lib\tcl83.lib<br> TCL_LIB: d:\tcl\lib\tcl83.lib<br>
</tt> </tt>
<a name="n8"></a><H4>2.2.1.3 Perl</H4> <H4><a name="Windows_nn8"></a>3.2.1.3 Perl</H4>
<b><tt>PERL5_INCLUDE</tt></b> : Set this to the directory containing perl.h<br> <b><tt>PERL5_INCLUDE</tt></b> : Set this to the directory containing perl.h<br>
@ -125,7 +123,7 @@ PERL5_INCLUDE: D:\nsPerl5.004_04\lib\CORE<br>
PERL5_LIB: D:\nsPerl5.004_04\lib\CORE\perl.lib<br> PERL5_LIB: D:\nsPerl5.004_04\lib\CORE\perl.lib<br>
</tt> </tt>
<a name="n9"></a><H4>2.2.1.4 Java</H4> <H4><a name="Windows_nn9"></a>3.2.1.4 Java</H4>
<b><tt>JAVA_INCLUDE</tt></b> : Set this to the directory containing jni.h<br> <b><tt>JAVA_INCLUDE</tt></b> : Set this to the directory containing jni.h<br>
@ -136,7 +134,7 @@ JAVA_INCLUDE: d:\jdk1.3\include<br>
JAVA_BIN: d:\jdk1.3\bin<br> JAVA_BIN: d:\jdk1.3\bin<br>
</tt> </tt>
<a name="n10"></a><H4>2.2.1.5 Ruby</H4> <H4><a name="Windows_nn10"></a>3.2.1.5 Ruby</H4>
<b><tt>RUBY_INCLUDE</tt></b> : Set this to the directory containing ruby.h<br> <b><tt>RUBY_INCLUDE</tt></b> : Set this to the directory containing ruby.h<br>
@ -147,25 +145,24 @@ RUBY_INCLUDE: D:\ruby\lib\ruby\1.6\i586-mswin32<br>
RUBY_LIB: D:\ruby\lib\mswin32-ruby16.lib<br> RUBY_LIB: D:\ruby\lib\mswin32-ruby16.lib<br>
</tt> </tt>
<a name="n11"></a><H4>2.2.1.6 C#</H4> <H4><a name="Windows_nn11"></a>3.2.1.6 C#</H4>
The C# examples do not require any environment variables to be set as a C# project file is included. The C# examples do not require any environment variables to be set as a C# project file is included.
Just open up the .sln solution file in Visual Studio .NET 2003 and do a Rebuild All from the Build menu. Just open up the .sln solution file in Visual Studio .NET 2003 and do a Rebuild All from the Build menu.
The accompanying C# and C++ project file are automatically used by the solution file. The accompanying C# and C++ project file are automatically used by the solution file.
<a name="n12"></a><H3>2.2.2 Instructions for using the Examples with other compilers</H3> <H3><a name="Windows_nn12"></a>3.2.2 Instructions for using the Examples with other compilers</H3>
If you do not have access to Visual C++ you will have to set up project files / Makefiles for your chosen compiler. There is a section in each of the language modules detailing what needs setting up using Visual C++ which may be of some guidance. Alternatively you may want to use Cygwin as described in the following section. If you do not have access to Visual C++ you will have to set up project files / Makefiles for your chosen compiler. There is a section in each of the language modules detailing what needs setting up using Visual C++ which may be of some guidance. Alternatively you may want to use Cygwin as described in the following section.
<a name="n13"></a><H2>2.3 SWIG on Cygwin and MinGW</H2> <H2><a name="Windows_nn13"></a>3.3 SWIG on Cygwin and MinGW</H2>
SWIG can also be compiled and run using <a href="http://www.cygwin.com">Cygwin</a> or <a href=http://www.mingw.org>MinGW</a> which provides a Unix like front end to Windows and comes free with gcc, an ANSI C/C++ compiler. However, this is not a recommended approach as the prebuilt executable is supplied. SWIG can also be compiled and run using <a href="http://www.cygwin.com">Cygwin</a> or <a href=http://www.mingw.org>MinGW</a> which provides a Unix like front end to Windows and comes free with gcc, an ANSI C/C++ compiler. However, this is not a recommended approach as the prebuilt executable is supplied.
<a name="swig_exe"></a> <H3><a name="swig_exe"></a>3.3.1 Building swig.exe on Windows</H3>
<a name="n14"></a><H3>2.3.1 Building swig.exe on Windows</H3>
If you want to replicate the build of swig.exe that comes with the download, follow the MinGW instructions below. If you want to replicate the build of swig.exe that comes with the download, follow the MinGW instructions below.
@ -173,7 +170,7 @@ This is not necessary to use the supplied swig.exe.
This information is provided for those that want to modify the SWIG source code in a Windows environment. This information is provided for those that want to modify the SWIG source code in a Windows environment.
Normally this is not needed, so most people will want to ignore this section. Normally this is not needed, so most people will want to ignore this section.
<a name="n15"></a><H4>2.3.1.1 Building swig.exe using MinGW and MSYS</H4> <H4><a name="Windows_nn15"></a>3.3.1.1 Building swig.exe using MinGW and MSYS</H4>
<ul> <ul>
@ -182,7 +179,7 @@ Normally this is not needed, so most people will want to ignore this section.
</ul> </ul>
<a name="n16"></a><H4>2.3.1.2 Building swig.exe using Cygwin</H4> <H4><a name="Windows_nn16"></a>3.3.1.2 Building swig.exe using Cygwin</H4>
Note that SWIG can also be built using Cygwin. Note that SWIG can also be built using Cygwin.
@ -190,9 +187,8 @@ However, the SWIG will then require the Cygwin DLL when executing.
Follow the Unix instructions in the README file in the SWIG root directory. Follow the Unix instructions in the README file in the SWIG root directory.
Note that the Cygwin environment will also allow one to regenerate the autotool generated files which are supplied with the release distribution. Note that the Cygwin environment will also allow one to regenerate the autotool generated files which are supplied with the release distribution.
These files are generated using the <tt>autogen.sh</tt> script and will only need regenerating in circumstances such as changing the build system. These files are generated using the <tt>autogen.sh</tt> script and will only need regenerating in circumstances such as changing the build system.
<p>
<a name="n17"></a><H4>2.3.1.3 Building swig.exe alternatives</H4> <H4><a name="Windows_nn17"></a>3.3.1.3 Building swig.exe alternatives</H4>
If you don't want to install Cygwin or MinGW, use a different compiler to build If you don't want to install Cygwin or MinGW, use a different compiler to build
@ -200,15 +196,12 @@ SWIG. For example, all the source code files can be added to a Visual C++ projec
file in order to build swig.exe from the Visual C++ IDE. file in order to build swig.exe from the Visual C++ IDE.
<a name="examples_cygwin"></a> <H3><a name="examples_cygwin"></a>3.3.2 Running the examples on Windows using Cygwin</H3>
<a name="n18"></a><H3>2.3.2 Running the examples on Windows using Cygwin</H3>
The examples and test-suite work as successfully on Cygwin as on any other Unix operating system. The examples and test-suite work as successfully on Cygwin as on any other Unix operating system.
The modules which are known to work are Python, Tcl, Perl, Ruby, Java and C#. The modules which are known to work are Python, Tcl, Perl, Ruby, Java and C#.
Follow the Unix instructions in the README file in the SWIG root directory to build the examples. Follow the Unix instructions in the README file in the SWIG root directory to build the examples.
<p>
</body> </body>
</html> </html>

View file

@ -1,96 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>SWIG1.3 Documentation</title> <title>SWIG-1.3 Documentation</title>
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<H1>SWIG1.3 Development Documentation</h1> <H1><a name="index"></a>SWIG-1.3 Development Documentation</h1>
Last update : SWIG-1.3.22 (?? ??? 2004) The SWIG documentation is available in one of the following formats.
<p>
<b>Authors:</b>
<ul> <ul>
<li>David Beazley (beazley@cs.uchicago.edu) <li>HTML documentation with one chapter per page.
<li>William Fulton (wsf@fultondesigns.co.uk) Please start with either the <a href="Sections.html#Sections">Sections summary</a> or the <a href="Contents.html#Contents">Detailed table of contents</a>.</li>
<li>Matthias Köppe (mkoeppe@mail.math.uni-magdeburg.de) <li>HTML documentation on a <a href="SWIGDocumentation.html">single HTML page</a>.</li>
<li>Lyle Johnson (lyle@users.sourceforge.net) <li><a href="SWIGDocumentation.pdf">PDF document</a>.</li>
<li>Richard Palmer (richard@magicality.org)
<li>Craig Files (cfiles@ftc.agilent.com)</li>
<li>Art Yerkes (ayerkes@users.sourceforge.net)</li>
<li>Jonah Beckford (beckford@usermail.com)</li>
</ul>
<P>
The SWIG documentation is currently being updated to reflect new SWIG
features and enhancements. However,this update process is currently
unfinished--there is a lot of old SWIG-1.1 documentation and it's going to
take some time to update all of it. Please pardon our dust (or volunteer
to help!).
<p>
<h3><a href="Contents.html">Detailed table of contents</a></h3>
<p>
<H3>SWIG Core Documentation</H3>
<ul>
<li><a href="Preface.html">Preface</a>
<li><a href="Introduction.html">Introduction</a>
<li><a href="Windows.html">Getting started on Windows</a>
<li><a href="Scripting.html">Scripting</a>
<li><a href="SWIG.html">SWIG Basics</a> (Read this!)
<li><a href="SWIGPlus.html">SWIG and C++</a>
<li><a href="Preprocessor.html">The SWIG preprocessor</a>.
<li><a href="Library.html">The SWIG Library</a>
<li><a href="Arguments.html">Argument handling</a>.
<li><a href="Typemaps.html">Typemaps</a>
<li><a href="Customization.html">Customization features</a>
<li><a href="Contract.html">Contracts</a>
<li><a href="Varargs.html">Variable length arguments</a>
<li><a href="Warnings.html">Warning messages</a>
<li><a href="Modules.html">Working with Modules</a>
</ul>
<H3>Language Module Documentation</h3>
<ul>
<li><a href="CSharp.html">C# support</a>
<li><a href="Chicken.html">Chicken support</a>
<li><a href="Guile.html">Guile support</a>
<li><a href="Java.html">Java support</a>
<li><a href="Ocaml.html">Ocaml support</a>
<li><a href="Perl5.html">Perl5 support</a>
<li><a href="Php.html">PHP support</a>
<li><a href="Python.html">Python support</a>
<li><a href="Ruby.html">Ruby support</a>
<li><a href="Tcl.html">Tcl support</a>
</ul>
<H3>Developer Documentation</h3>
<ul>
<li><a href="Extending.html">Extending SWIG</a>
</ul>
<p>
<h3>Documentation that has not yet been updated</h3>
This documentation has not been updated, but most of the topics
still apply to the current release. Make sure you read the
<a href="SWIG.html">SWIG Basics</a> chapter before reading
any of these chapters. Also, SWIG-1.3.10 features extensive changes to the
implementation of typemaps. Make sure you read the <a href="Typemaps.html">Typemaps</a>
chapter above if you are using this feature.
<ul>
<li><a href="Advanced.html">Advanced topics</a> (see <a href="Modules.html">Modules</a> for updated information).
</ul>
<h3>Documentation not yet written (volunteers needed)</h3>
<ul>
<li>Mzscheme module
</ul> </ul>
</body> </body>