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>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>15 Advanced Topics</H1>
<H1><a name="Advanced"></a>29 Advanced Topics</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Creating multi-module packages</a>
<li><a href="#Advanced_nn2">Creating multi-module packages</a>
<ul>
<li><a href="#n3">Runtime support (and potential problems)</a>
<li><a href="#n4">Why doesn't C++ inheritance work between modules?</a>
<li><a href="#n5">The SWIG runtime library</a>
<li><a href="#n6">A few dynamic loading gotchas</a>
<li><a href="#Advanced_nn3">Runtime support (and potential problems)</a>
<li><a href="#Advanced_nn4">Why doesn't C++ inheritance work between modules?</a>
<li><a href="#Advanced_nn5">The SWIG runtime library</a>
<li><a href="#Advanced_nn6">A few dynamic loading gotchas</a>
</ul>
<li><a href="#n7">Dynamic Loading of C++ modules</a>
<li><a href="#n8">Inside the SWIG type-checker</a>
<li><a href="#Advanced_nn7">Dynamic Loading of C++ modules</a>
<li><a href="#Advanced_nn8">Inside the SWIG type-checker</a>
<ul>
<li><a href="#n9">Type equivalence</a>
<li><a href="#n10">Type casting</a>
<li><a href="#n11">Why a name based approach?</a>
<li><a href="#n12">Performance of the type-checker</a>
<li><a href="#Advanced_nn9">Type equivalence</a>
<li><a href="#Advanced_nn10">Type casting</a>
<li><a href="#Advanced_nn11">Why a name based approach?</a>
<li><a href="#Advanced_nn12">Performance of the type-checker</a>
</ul>
</ul>
<!-- INDEX -->
@ -32,27 +32,42 @@
<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#.
<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.
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).
If you create a system consisting of many modules, each one will have an identical copy of these runtime libraries :<p>
<center><img src="ch11.1.png"></center><p>
If you create a system consisting of many modules, each one will have an identical copy of these runtime libraries :
</p>
<center><img src="ch11.1.png" alt="Modules 1-N each have their own identical runtime library"></center>
<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>
<a name="n4"></a><H3>15.1.2 Why doesn't C++ inheritance work between modules?</H3>
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>
<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>
<blockquote><pre>// File : a.i
Consider for a moment the following two interface files :
</p>
<blockquote><pre>
// File : a.i
%module a
// Here is a base class
@ -76,8 +91,11 @@ public:
};
</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>
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>
[beazley@guinness shadow]$ <b>python</b>
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.
&gt;&gt;&gt;
</pre></blockquote>
<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>
<center><img src="ch11.2.png"></center><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>
<center><img src="ch11.2.png" alt="a accepts a, b accepts a and b, b accepts b"></center>
<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>
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>
<a name="n5"></a><H3>15.1.3 The SWIG runtime library</H3>
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>
<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.
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>
<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>
</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>
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>
When completed you should now end up with a collection of modules like this:
</p>
<center><img src="ch11.3.png" alt="Modules 1-N using single runtime"></center>
<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.
</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>
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>
<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};
@ -138,31 +173,44 @@ static void *__embedfunc(void *a) { return a};
void *__embedfunc(void *);
%include tclsh.i
</pre></blockquote>
<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>
<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>
<blockquote><pre>
% <b>swig -c -tcl mytclsh.i</b>
% <b>gcc mytclsh_wrap.c -I/usr/local/include -L/usr/local/lib -ltcl -lswigruntcl -ldl -lm \
-o tclsh</b>
</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>
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>
To make new dynamically loadable SWIG modules, simply compile as follows :
</p>
<blockquote><pre>
% <b>swig -c -tcl example.i</b>
% <b>gcc -c example_wrap.c -I/usr/local/include</b>
% <b>ld -shared example_wrap.o -o example.so</b>
</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.
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>
2. Using shared library versions of the runtime library<p>
2. Using shared library versions of the runtime library
</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>
% <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++
</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.
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>
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>
<blockquote><pre>Unable to locate libexample.so</pre></blockquote>
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.
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>
<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:<p>
<p>
<blockquote><pre>% <b>ld -shared example_wrap.o example.o -rpath /home/beazley/packages/lib \
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>
<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>
</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>
If all else fails, pull up the man pages for your linker and start playing around.<p>
<a name="n7"></a><H2>15.2 Dynamic Loading of C++ modules</H2>
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>
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>
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>
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>
<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.
@ -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>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>
<p>
The SWIG distribution contains some additional documentation about C++ modules in the Doc directory as well.<p>
<a name="n8"></a><H2>15.3 Inside the SWIG type-checker</H2>
The SWIG distribution contains some additional documentation about C++ modules in the Doc directory as well.
</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>
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>
<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 double Float;
</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>
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>
double =&gt; { Real, Float }
Real =&gt; { double, Float }
Float =&gt; { double, Real }
RealPtr =&gt; { Real * }
Real * =&gt; { RealPtr }
</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>
Derived versions of the various datatypes are also legal. For example, if you had a function like this,<p>
<p>
<blockquote><pre>void bar(Float ***a);
When you declare a function such as the following :
</p>
<blockquote><pre>
void foo(Real *a);
</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>
<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 %{
SWIG_RegisterMapping("Float_ppp","RealPtr_pp",0);
%}
</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>
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>
<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 C : public B { };
class D {};
class E : public C, public D {};
</pre></blockquote>
The type-checker encodes this into the following sets :<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"
C =&gt; { E } "E isa C"
D =&gt; { E } "E isa D"
E =&gt; { }
</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>
<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;
A *out = (A *) in; // Cast using C++
return (void *) out;
}
</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>
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>
<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>I believe using the original names of datatypes is more intuitive than munging them into something completely different.
</ul>
<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>
<a name="n12"></a><H3>15.3.4 Performance of the type-checker</H3>
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>
<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>
The type-checker performs the following steps when matching a datatype :
</p>
<dl>
<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.
</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>
</body>

View file

@ -5,22 +5,22 @@
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>7 Argument Handling</H1>
<H1><a name="Arguments"></a>9 Argument Handling</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">The typemaps.i library</a>
<li><a href="#Arguments_nn2">The typemaps.i library</a>
<ul>
<li><a href="#n3">Introduction</a>
<li><a href="#n4">Input parameters</a>
<li><a href="#n5">Output parameters</a>
<li><a href="#n6">Input/Output parameters</a>
<li><a href="#n7">Using different names</a>
<li><a href="#Arguments_nn3">Introduction</a>
<li><a href="#Arguments_nn4">Input parameters</a>
<li><a href="#Arguments_nn5">Output parameters</a>
<li><a href="#Arguments_nn6">Input/Output parameters</a>
<li><a href="#Arguments_nn7">Using different names</a>
</ul>
<li><a href="#n8">Applying constraints to input values</a>
<li><a href="#Arguments_nn8">Applying constraints to input values</a>
<ul>
<li><a href="#n9">Simple constraint example</a>
<li><a href="#n10">Constraint methods</a>
<li><a href="#n11">Applying constraints to new datatypes</a>
<li><a href="#Arguments_nn9">Simple constraint example</a>
<li><a href="#Arguments_nn10">Constraint methods</a>
<li><a href="#Arguments_nn11">Applying constraints to new datatypes</a>
</ul>
</ul>
<!-- 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
return multiple values through the arguments of a function. This chapter
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
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:
<p>
<blockquote><pre>void add(double a, double b, double *result) {
<blockquote><pre>
void add(double a, double b, double *result) {
*result = a + b;
}
</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
does not examine function bodies, it has no way to know that this is
the underlying behavior.
</p>
<p>
One way to deal with this is to use the
<tt>typemaps.i</tt> library file and write interface code like this:
</p>
<p>
<blockquote><pre>// Simple example using typemaps
<blockquote><pre>
// Simple example using typemaps
%module example
%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);
</pre></blockquote>
<p>
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
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
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>
When the resulting module is created, you can now use the function
like this (shown for Python):
</p>
<p>
<blockquote><pre>
>>> a = add(3,4)
>>> print a
&gt;&gt;&gt; a = add(3,4)
&gt;&gt;&gt; print a
7
>>>
&gt;&gt;&gt;
</pre></blockquote>
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>
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:
</p>
<p>
<blockquote><pre>
%module example
%include "typemaps.i"
@ -122,6 +126,7 @@ In this case, the <tt>double *OUTPUT</tt> rule is applied to all of the function
<p>
Typemap transformations can even be extended to multiple return values.
For example, consider this code:
</p>
<blockquote>
<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:
<blockquote><pre>
>>> w,h = genwinsize(wid)
>>> print w
&gt;&gt;&gt; w,h = genwinsize(wid)
&gt;&gt;&gt; print w
400
>>> print h
&gt;&gt;&gt; print h
300
>>>
&gt;&gt;&gt;
</pre>
</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
used to associate typemap rules to datatypes, you can also use the
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
%include "typemaps.i"
@ -166,12 +173,13 @@ else. To clear a typemap, the <tt>%clear</tt> directive should be used. For e
</pre>
</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>
The following typemaps instruct SWIG that a pointer really only holds a single
input value:
</p>
<blockquote><pre>
int *INPUT
@ -195,29 +203,33 @@ double add(double *a, double *b) {
Now, consider this SWIG interface:
<p>
<blockquote><pre>%module example
<blockquote><pre>
%module example
%include "typemaps.i"
...
extern double add(double *INPUT, double *INPUT);
</pre></blockquote>
When the function is used in the scripting language interpreter, it will work like this:
<p>
When the function is used in the scripting language interpreter, it will work like this:
</p>
<blockquote><pre>
result = add(3,4)
</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
function. When used, you do not need to supply the argument when
calling the function. Instead, one or more output values are returned.
</p>
<p>
<blockquote><pre>int *OUTPUT
<blockquote><pre>
int *OUTPUT
short *OUTPUT
long *OUTPUT
unsigned int *OUTPUT
@ -227,18 +239,20 @@ double *OUTPUT
float *OUTPUT
</pre></blockquote>
These methods can be used as shown in an earlier example. For example, if you have this C function :<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;
}
</pre></blockquote>
<p>
A SWIG interface file might look like this :<p>
A SWIG interface file might look like this :</p>
<p>
<blockquote><pre>%module example
<blockquote><pre>
%module example
%include "typemaps.i"
...
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>
If the function also returns a value, it is returned along with the argument. For example,
if you had this:
</p>
<blockquote><pre>
extern int foo(double a, double b, double *OUTPUT);
@ -265,11 +280,12 @@ iresult, dresult = foo(3.5, 2)
</pre>
</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
the following typemaps :<p>
the following typemaps :</p>
<blockquote><pre>
int *INOUT
@ -283,30 +299,33 @@ float *INOUT
</pre></blockquote>
A C function that uses this might be something like this:<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);
}
</pre></blockquote>
To make x function as both and input and output value, declare the
function like this in an interface file :<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
...
extern void negate(double *INOUT);
</pre></blockquote>
Now within a script, you can simply call the function normally :<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>
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>
<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.
</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>
<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 };
// 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:
<p>
<blockquote><pre>%clear double *result;
<blockquote><pre>
%clear double *result;
%clear Int32 *in, long *x;
</pre></blockquote>
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.
<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
@ -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
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>
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
%include "constraints.i"
@ -375,15 +398,17 @@ void free(void *NONNULL); // Non-NULL pointers only
</pre></blockquote>
<p>
The behavior of this file is exactly as you would expect. If any of
the arguments violate the constraint condition, a scripting language
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>
POSITIVE Any number &gt; 0 (not zero)
@ -395,15 +420,16 @@ NONNULL Non-NULL pointer (pointers only).
</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
is easy to apply it to new datatypes using <tt>%apply</tt>. For
example :<p>
<p>
example :</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 a constraint to a pointer type
@ -411,17 +437,17 @@ example :<p>
</pre></blockquote>
<p>
The special types of "Number" and "Pointer" can be applied to any
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>%clear Real in;
<blockquote><pre>
%clear Real in;
%clear Vector *;
</pre></blockquote>
<p><hr>
<hr>
<address>SWIG 1.3 - Last Modified : October 13, 2002</address>
</body>
</html>

View file

@ -4,12 +4,12 @@
<title>SWIG and C#</title>
</head>
<body bgcolor="#FFFFFF">
<a name="n1"></a><H1>15 SWIG and C#</H1>
<H1><a name="CSharp"></a>16 SWIG and C#</H1>
<!-- INDEX -->
<ul>
</ul>
<!-- INDEX -->
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 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>
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,
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.
<p>
@ -52,7 +52,7 @@ There is no implementation for type unsafe enums - not deemed necessary.
<li>
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.
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,
@ -70,20 +70,20 @@ Likewise there is no need for an equivalent to <tt>%javaexception</tt>.
Typemap equivalent names:
<blockquote><pre>
jni -> ctype
jtype -> imtype
jstype -> cstype
javain -> csin
javaout -> csout
javainterfaces -> csinterfaces and csinterfaces_derived
javabase -> csbase
javaclassmodifiers -> csclassmodifiers
javacode -> cscode
javaimports -> csimports
javabody -> csbody
javafinalize -> csfinalize
javadestruct -> csdestruct
javadestruct_derived -> csdestruct_derived
jni -&gt; ctype
jtype -&gt; imtype
jstype -&gt; cstype
javain -&gt; csin
javaout -&gt; csout
javainterfaces -&gt; csinterfaces and csinterfaces_derived
javabase -&gt; csbase
javaclassmodifiers -&gt; csclassmodifiers
javacode -&gt; cscode
javaimports -&gt; csimports
javabody -&gt; csbody
javafinalize -&gt; csfinalize
javadestruct -&gt; csdestruct
javadestruct_derived -&gt; csdestruct_derived
</pre></blockquote>
</li>
@ -101,30 +101,30 @@ csvarout C# code property get typemap
<li>
Feature equivalent names:
<blockquote><pre>
%javaconst -> %csconst
%javaconstvalue -> %csconstvalue
%javamethodmodifiers -> %csmethodmodifiers
%javaconst -&gt; %csconst
%javaconstvalue -&gt; %csconstvalue
%javamethodmodifiers -&gt; %csmethodmodifiers
</pre></blockquote>
</li>
<li>
Pragma equivalent names:
<blockquote><pre>
%pragma(java) -> %pragma(csharp)
jniclassbase -> imclassbase
jniclassclassmodifiers -> imclassclassmodifiers
jniclasscode -> imclasscode
jniclassimports -> imclassimports
jniclassinterfaces -> imclassinterfaces
%pragma(java) -&gt; %pragma(csharp)
jniclassbase -&gt; imclassbase
jniclassclassmodifiers -&gt; imclassclassmodifiers
jniclasscode -&gt; imclasscode
jniclassimports -&gt; imclassimports
jniclassinterfaces -&gt; imclassinterfaces
</pre></blockquote>
</li>
<li>
Special variable equivalent names:
<blockquote><pre>
$javaclassname -> $csclassname
$javainput -> $csinput
$jnicall -> $imcall
$javaclassname -&gt; $csclassname
$javainput -&gt; $csinput
$jnicall -&gt; $imcall
</pre></blockquote>
</li>

View file

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

File diff suppressed because it is too large Load diff

View file

@ -5,13 +5,13 @@
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>10 Contracts</H1>
<H1><a name="Contract"></a>12 Contracts</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">The %contract directive</a>
<li><a href="#n3">%contract and classes</a>
<li><a href="#n4">Constant aggregation and %aggregate_check</a>
<li><a href="#n5">Notes</a>
<li><a href="#Contract_nn2">The %contract directive</a>
<li><a href="#Contract_nn3">%contract and classes</a>
<li><a href="#Contract_nn4">Constant aggregation and %aggregate_check</a>
<li><a href="#Contract_nn5">Notes</a>
</ul>
<!-- 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.
When one of the rules is violated by a script, a runtime exception is
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
@ -42,9 +43,9 @@ is a simple example:
<pre>
%contract sqrt(double x) {
require:
x >= 0;
x &gt;= 0;
ensure:
sqrt >= 0;
sqrt &gt;= 0;
}
...
@ -65,24 +66,26 @@ cases, the conditions that must hold must be specified as boolean expressions.
<p>
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).
</p>
<p>
Once a contract has been specified, it modifies the behavior of the
resulting module. For example:
</p>
<blockquote>
<pre>
>>> example.sqrt(2)
&gt;&gt;&gt; example.sqrt(2)
1.4142135623730951
>>> example.sqrt(-2)
&gt;&gt;&gt; example.sqrt(-2)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
RuntimeError: Contract violation: require: (arg1>=0)
>>>
File "&lt;stdin&gt;", line 1, in ?
RuntimeError: Contract violation: require: (arg1&gt;=0)
&gt;&gt;&gt;
</pre>
</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:
@ -91,14 +94,14 @@ The <tt>%contract</tt> directive can also be applied to class methods and constr
<pre>
%contract Foo::bar(int x, int y) {
require:
x > 0;
x &gt; 0;
ensure:
bar > 0;
bar &gt; 0;
}
%contract Foo::Foo(int a) {
require:
a > 0;
a &gt; 0;
}
class Foo {
@ -127,12 +130,12 @@ In addition to this, separate contracts can be applied to both the base class an
<pre>
%contract Foo::bar(int x, int) {
require:
x > 0;
x &gt; 0;
}
%contract Spam::bar(int, int y) {
require:
y > 0;
y &gt; 0;
}
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,
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:
@ -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
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
in SWIG-1.3.20.
<p><hr>
<hr>
<address>SWIG 1.3 - Last Modified : November 12, 2003</address>
</body>

View file

@ -5,19 +5,19 @@
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>9 Customization Features</H1>
<H1><a name="Customization"></a>11 Customization Features</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Exception handling with %exception</a>
<li><a href="#exception">Exception handling with %exception</a>
<ul>
<li><a href="#n3">Handling exceptions in C code</a>
<li><a href="#n4">Exception handling with longjmp()</a>
<li><a href="#n5">Handling C++ exceptions</a>
<li><a href="#n6">Defining different exception handlers</a>
<li><a href="#n7">Using The SWIG exception library</a>
<li><a href="#Customization_nn3">Handling exceptions in C code</a>
<li><a href="#Customization_nn4">Exception handling with longjmp()</a>
<li><a href="#Customization_nn5">Handling C++ exceptions</a>
<li><a href="#Customization_nn6">Defining different exception handlers</a>
<li><a href="#Customization_nn7">Using The SWIG exception library</a>
</ul>
<li><a href="#n8">Object ownership and %newobject</a>
<li><a href="#n9">Features and the %feature directive</a>
<li><a href="#ownership">Object ownership and %newobject</a>
<li><a href="#features">Features and the %feature directive</a>
</ul>
<!-- INDEX -->
@ -31,15 +31,16 @@ describes some of these customization techniques. First, a discussion
of exception handling is presented. Then, a more general-purpose
customization mechanism known as "features" is described.
<a name="exception">
<a name="n2"></a><H2>9.1 Exception handling with %exception</H2>
<H2><a name="exception"></a>11.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>
<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 {
$action
}
@ -49,31 +50,34 @@ handler. For example, you can specify the following:
}
}
</pre></blockquote>
<p>
<p>
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
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>
or <tt>%noexception</tt> with no code. For example:
<p>
<blockquote><pre>%exception; // Deletes any previously defined handler
</p>
<blockquote><pre>
%exception; // Deletes any previously defined handler
</pre></blockquote>
<p>
<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>
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>
<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 */
static char error_message[256];
@ -94,11 +98,13 @@ char *check_exception() {
</pre></blockquote>
<p>
To use these functions, functions simply call
<tt>throw_exception()</tt> to indicate an error occurred. For example
:<p>
<p>
<blockquote><pre>double inv(double x) {
:</p>
<blockquote><pre>
double inv(double x) {
if (x != 0) return 1.0/x;
else {
throw_exception("Division by zero");
@ -108,11 +114,12 @@ To use these functions, functions simply call
</pre></blockquote>
To catch the exception, you can write a simple exception handler such
as the following (shown for Perl5) :<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;
clear_exception();
$action
@ -121,10 +128,12 @@ as the following (shown for Perl5) :<p>
}
}
</pre></blockquote>
<p>
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
@ -157,20 +166,22 @@ extern int exception_status;
</pre></blockquote>
Now, within a C program, you can do the following :<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;
else throw(DivisionByZero);
}
</pre></blockquote>
Finally, to create a SWIG exception handler, write the following :<p>
<p>
<blockquote><pre>%{
Finally, to create a SWIG exception handler, write the following :</p>
<blockquote><pre>
%{
#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
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>
<blockquote><pre>%exception {
Handling C++ exceptions is also straightforward. For example:
</p>
<blockquote><pre>
%exception {
try {
$action
} catch(RangeError) {
@ -214,17 +227,18 @@ Handling C++ exceptions is also straightforward. For example:
</pre></blockquote>
The exception types need to be declared as classes elsewhere, possibly
in a header file :<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 OutOfMemory {};
</pre>
</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
@ -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,
defining one universal exception handler may be unwieldy and result
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
<tt>%exception</tt> directive. One approach is to only place it around
critical pieces of code. For example:
</p>
<p>
<blockquote><pre>%exception {
<blockquote><pre>
%exception {
... your exception handler ...
}
/* 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>
<tt>%exception</tt> can even be used to pinpoint a precise declaration when overloading is used. For example:
</p>
<blockquote>
<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
%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
language independent exceptions in your interfaces. To use it, simply
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
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>// Language independent exception handler
<blockquote><pre>
// Language independent exception handler
%include exception.i
%exception {
@ -376,12 +393,13 @@ common scripting language exceptions in a portable manner. For example :<p>
</pre></blockquote>
<p>
As arguments, <tt>SWIG_exception()</tt> takes an error type code (an
integer) and an error message string. The currently supported error
types are :<p>
types are :</p>
<p>
<blockquote><pre>SWIG_MemoryError
<blockquote><pre>
SWIG_MemoryError
SWIG_IOError
SWIG_RuntimeError
SWIG_IndexError
@ -393,14 +411,14 @@ SWIG_ValueError
SWIG_SystemError
SWIG_UnknownError
</pre></blockquote>
<p>
<p>
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
functions.
</p>
<a name="ownership">
<a name="n8"></a><H2>9.2 Object ownership and %newobject</H2>
<H2><a name="ownership"></a>11.2 Object ownership and %newobject</H2>
A common problem in some applications is managing proper ownership of objects. For
@ -424,6 +442,7 @@ returned object was newly created).
<p>
To fix this, you can provide an extra hint to the code generator using
the <tt>%newobject</tt> directive. For example:
</p>
<blockquote>
<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
methods for which <tt>%newobject</tt> has been applied and is commonly used to clean-up string
results. For example:
</p>
<blockquote>
<pre>
@ -473,6 +493,7 @@ The "newfree" typemap in the example simply releases this memory.
<p>
<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:
</p>
<blockquote>
<pre>
@ -485,6 +506,7 @@ For now this is still supported but is deprecated.
<p>
<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:
</p>
<blockquote>
<pre>
@ -494,8 +516,7 @@ char *strdup(const char *s);
</blockquote>
The results might not be what you expect.
<a name="features"></a>
<a name="n9"></a><H2>9.3 Features and the %feature directive</H2>
<H2><a name="features"></a>11.3 Features and the %feature directive</H2>
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>
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.
</p>
<p>
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:
</p>
<blockquote>
<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
attached to <em>every</em> declaration that follows. This is how global exception handlers
are defined. For example:
</p>
<blockquote>
<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.
<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
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:
</p>
<blockquote>
<pre>
@ -647,7 +671,7 @@ public:
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>
</body>

File diff suppressed because it is too large Load diff

View file

@ -7,35 +7,35 @@
<body bgcolor="#ffffff">
<a name="n1"></a><H1>16 SWIG and Guile</H1>
<H1><a name="Guile"></a>18 SWIG and Guile</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Meaning of "Module"</a>
<li><a href="#n3">Using the SCM or GH Guile API</a>
<li><a href="#n4">Linkage</a>
<li><a href="#Guile_nn2">Meaning of "Module"</a>
<li><a href="#Guile_nn3">Using the SCM or GH Guile API</a>
<li><a href="#Guile_nn4">Linkage</a>
<ul>
<li><a href="#n5">Simple Linkage</a>
<li><a href="#n6">Passive Linkage</a>
<li><a href="#n7">Native Guile Module Linkage</a>
<li><a href="#n8">Old Auto-Loading Guile Module Linkage</a>
<li><a href="#n9">Hobbit4D Linkage</a>
<li><a href="#n10">General Remarks on Multiple SWIG Modules</a>
<li><a href="#Guile_nn5">Simple Linkage</a>
<li><a href="#Guile_nn6">Passive Linkage</a>
<li><a href="#Guile_nn7">Native Guile Module Linkage</a>
<li><a href="#Guile_nn8">Old Auto-Loading Guile Module Linkage</a>
<li><a href="#Guile_nn9">Hobbit4D Linkage</a>
<li><a href="#Guile_nn10">General Remarks on Multiple SWIG Modules</a>
</ul>
<li><a href="#n11">Underscore Folding</a>
<li><a href="#n12">Typemaps</a>
<li><a href="#n13">Representation of pointers as smobs</a>
<li><a href="#Guile_nn11">Underscore Folding</a>
<li><a href="#Guile_nn12">Typemaps</a>
<li><a href="#Guile_nn13">Representation of pointers as smobs</a>
<ul>
<li><a href="#n14">GH Smobs</a>
<li><a href="#n15">SCM Smobs</a>
<li><a href="#n16">Garbage Collection</a>
<li><a href="#Guile_nn14">GH Smobs</a>
<li><a href="#Guile_nn15">SCM Smobs</a>
<li><a href="#Guile_nn16">Garbage Collection</a>
</ul>
<li><a href="#n17">Exception Handling</a>
<li><a href="#n18">Procedure documentation</a>
<li><a href="#n19">Procedures with setters</a>
<li><a href="#n20">GOOPS Shadow Classes</a>
<li><a href="#Guile_nn17">Exception Handling</a>
<li><a href="#Guile_nn18">Procedure documentation</a>
<li><a href="#Guile_nn19">Procedures with setters</a>
<li><a href="#Guile_nn20">GOOPS Shadow Classes</a>
<ul>
<li><a href="#n21">Naming Issues</a>
<li><a href="#n22">Linking</a>
<li><a href="#Guile_nn21">Naming Issues</a>
<li><a href="#Guile_nn22">Linking</a>
</ul>
</ul>
<!-- INDEX -->
@ -45,7 +45,7 @@
<p>
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>
@ -53,13 +53,13 @@ There are three different concepts of "module" involved, defined
separately for SWIG, Guile, and Libtool. To avoid horrible confusion,
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
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
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 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
@ -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.
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>
@ -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
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
@ -170,6 +170,8 @@ Since SWIG doesn't know how
to load your extension module (with <code>dynamic-link</code> or
<code>load-extension</code>), you need to supply this
information by including a directive like this in the interface file:
</p>
<blockquote>
<pre>
%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
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
@ -195,7 +197,7 @@ package name (see below).
<p>You should use passive linkage rather than simple linkage when you
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
@ -236,7 +238,7 @@ Newer Guile versions have a shorthand procedure for this:
</blockquote>
</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
@ -262,7 +264,7 @@ option, SWIG generates an exported module initialization function with
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>
@ -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
using the "-package" command line option to set the part of the module
name before the last symbol. For example, both command lines:
</p>
<blockquote>
<pre>
@ -279,13 +282,15 @@ swig -guile -package my/lib -module foo foo.i
</pre>
</blockquote>
<p>
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
my/lib/libfoo.so.X.Y.Z and friends. This scheme is still very
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
@ -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
to generate the runtime code instead of placing the runtime code into a
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>
@ -312,7 +317,7 @@ complained so far.
<code>%rename</code> to specify the Guile name of the wrapped
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>
@ -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
back to this behavior, use
<blockquote>
<pre>%values_as_list;</pre>
<pre>
%values_as_list;</pre>
</blockquote>
<li><em>Multiple values as vectors.</em>
By issuing
<blockquote>
<pre>%values_as_vector;</pre>
<pre>
%values_as_vector;</pre>
</blockquote>
vectors instead of lists will be used.
<li><em>Multiple values for multiple-value continuations.</em>
<strong>This is the most elegant way.</strong> By issuing
<blockquote>
<pre>%multiple_values;</pre>
<pre>
%multiple_values;</pre>
</blockquote>
multiple values are passed to the multiple-value
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>
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>
@ -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
function <code>SWIG_ConvertPtr()</code>, passing a pointer to a struct
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
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>
@ -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
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.
@ -430,7 +438,7 @@ in the smob tag. If a generated GOOPS module has been loaded, smobs will be wra
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
@ -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
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
is exactly like described in <a href="Customization.html#n9">
Section 9.2 Object ownership and %newobject</a> in the SWIG manual. All typemaps use an $owner var, and
is exactly like described in <a href="Customization.html#ownership">
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>
<a name="n17"></a><H2>16.7 Exception Handling</H2>
<H2><a name="Guile_nn17"></a>18.7 Exception Handling</H2>
<p>
@ -468,7 +476,7 @@ mapping:
The default when not specified here is to use "swig-error".
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
@ -501,7 +509,7 @@ like this:
typemap argument <code>doc</code>. See <code>Lib/guile/typemaps.i</code> for
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
@ -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
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
@ -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,
then the generated file will contain accessor methods for all the
slots in the classes and for global variables. The input class</p>
<blockquote><pre> class Foo {
<blockquote><pre>
class Foo {
public:
Foo(int i) : a(i) {}
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); }
</pre></blockquote>
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
#:slot-ref primitive:Foo-a-get
#: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 )
</pre></blockquote>
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
#:slot-ref primitive:Foo-a-get
#: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>
<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" %}
@ -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
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
<blockquote><pre>;;...
<blockquote><pre>
;;...
(define-method (someFunc (swig_smob &lt;Foo&gt;))
(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
<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
@ -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.
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).
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. 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:)))
</pre></blockquote>
<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
@ -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
<code>(export ...)</code> code that would be exported into the scmstub file is exported at the bottom
of the generated GOOPS guile-module.
The <code>%goops</code> directive should contain code to load the .so library.</li>
<blockquote><pre>%goops %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
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") %}
</pre></blockquote>
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)
<blockquote><pre>(define-module (my modules foo))
<blockquote><pre>
(define-module (my modules foo))
;; %goops directive goes here
(load-extension "./foo.so" "scm_init_my_modules_foo_module")
(use-modules (oop goops) (Swig common))
</pre></blockquote>
</li>
<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>
@ -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>
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
whatever code is needed to load the <i>Module-primitive.scm</i> file into guile.</li>
<blockquote><pre>%scheme %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
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") %}
// only include the following definition if (my modules foo) cannot
// be loaded automatically
%goops %{
@ -740,7 +760,8 @@ whatever code is needed to load the <i>Module-primitive.scm</i> file into guile.
%}
</pre></blockquote>
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)
(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:)))
</pre></blockquote>
</li>
<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
(<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>
<blockquote><pre>%goops %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
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") %}
</pre></blockquote>
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)
(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:)))
</pre></blockquote>
</li>
</ul>
<p><b>(Swig common)</b>: The generated GOOPS guile-module also imports definitions from the

View file

@ -5,29 +5,29 @@
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>1 Introduction</H1>
<H1><a name="Introduction"></a>2 Introduction</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">What is SWIG?</a>
<li><a href="#n3">Why use SWIG?</a>
<li><a href="#n4">A SWIG example</a>
<li><a href="#Introduction_nn2">What is SWIG?</a>
<li><a href="#Introduction_nn3">Why use SWIG?</a>
<li><a href="#Introduction_nn4">A SWIG example</a>
<ul>
<li><a href="#n5">SWIG interface file</a>
<li><a href="#n6">The swig command</a>
<li><a href="#n7">Building a Perl5 module</a>
<li><a href="#n8">Building a Python module</a>
<li><a href="#n9">Shortcuts</a>
<li><a href="#Introduction_nn5">SWIG interface file</a>
<li><a href="#Introduction_nn6">The swig command</a>
<li><a href="#Introduction_nn7">Building a Perl5 module</a>
<li><a href="#Introduction_nn8">Building a Python module</a>
<li><a href="#Introduction_nn9">Shortcuts</a>
</ul>
<li><a href="#n10">Supported C/C++ language features</a>
<li><a href="#n11">Non-intrusive interface building</a>
<li><a href="#n12">Hands off code generation</a>
<li><a href="#n13">SWIG and freedom</a>
<li><a href="#Introduction_nn10">Supported C/C++ language features</a>
<li><a href="#Introduction_nn11">Non-intrusive interface building</a>
<li><a href="#Introduction_nn12">Hands off code generation</a>
<li><a href="#Introduction_nn13">SWIG and freedom</a>
</ul>
<!-- 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
@ -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
of SWIG include:
<p>
<ul>
<li>Building interpreted interfaces to existing C programs.
<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
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
@ -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
in programs that resemble this:
<p>
<ul>
<li>A collection of functions and variables that do something useful.
<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
every aspect of the language bindings. This is the main reason why SWIG has such a large
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
following C code: <p>
following C code:
<p>
<blockquote><pre>/* File : example.c */
<blockquote><pre>
/* File : example.c */
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
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
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>
@ -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
module that will be created by SWIG. The <tt>%{,%}</tt> block
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
build a Tcl module (under Linux) as follows :<p>
build a Tcl module (under Linux) as follows :
<p>
<blockquote><pre>unix &gt; <b>swig -tcl example.i</b>
<blockquote><pre>
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 -shared example.o example_wrap.o -o example.so</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
and variables declared in the SWIG interface. A look at the file
<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
any changes type the following (shown for Solaris):<p>
any changes type the following (shown for Solaris):
<p>
<p>
<blockquote><pre>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 \
-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
@ -241,13 +237,13 @@ unix &gt;
</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>unix &gt; <b>swig -python example.i</b>
<blockquote><pre>
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 -shared example.o example_wrap.o -o _example.so</b>
unix &gt; <b>python</b>
@ -263,16 +259,16 @@ Type "copyright", "credits" or "license" for more information.
7.5
</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
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
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>unix &gt; <b>swig -perl5 -module example example.h</b>
<blockquote><pre>
unix &gt; <b>swig -perl5 -module example example.h</b>
unix &gt; <b>gcc -c example.c example_wrap.c \
-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>
@ -287,7 +283,7 @@ print $example::My_variable + 4.5, "\n";
7.5
</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
@ -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.
<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
@ -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
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
@ -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
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.
@ -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
non-portable or unreliable programming features.
<p><hr>
<hr>
<address>SWIG 1.3 - Last Modified : August 10, 2002</address>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -5,32 +5,32 @@
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>13 SWIG library</H1>
<H1><a name="Library"></a>8 SWIG library</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">The %include directive and library search path</a>
<li><a href="#n3">C Arrays and Pointers</a>
<li><a href="#Library_nn2">The %include directive and library search path</a>
<li><a href="#Library_nn3">C Arrays and Pointers</a>
<ul>
<li><a href="#n4">cpointer.i</a>
<li><a href="#n5">carrays.i</a>
<li><a href="#n6">cmalloc.i</a>
<li><a href="#n7">cdata.i</a>
<li><a href="#Library_nn4">cpointer.i</a>
<li><a href="#Library_nn5">carrays.i</a>
<li><a href="#Library_nn6">cmalloc.i</a>
<li><a href="#Library_nn7">cdata.i</a>
</ul>
<li><a href="#n8">C String Handling</a>
<li><a href="#Library_nn8">C String Handling</a>
<ul>
<li><a href="#n9">Default string handling</a>
<li><a href="#n10">Passing binary data</a>
<li><a href="#n11">Using %newobject to release memory</a>
<li><a href="#n12">cstring.i</a>
<li><a href="#Library_nn9">Default string handling</a>
<li><a href="#Library_nn10">Passing binary data</a>
<li><a href="#Library_nn11">Using %newobject to release memory</a>
<li><a href="#Library_nn12">cstring.i</a>
</ul>
<li><a href="#n13">C++ Library</a>
<li><a href="#Library_nn13">C++ Library</a>
<ul>
<li><a href="#n14">std_string.i</a>
<li><a href="#n15">std_vector.i</a>
<li><a href="#Library_nn14">std_string.i</a>
<li><a href="#Library_nn15">std_vector.i</a>
</ul>
<li><a href="#n16">Utility Libraries</a>
<li><a href="#Library_nn16">Utility Libraries</a>
<ul>
<li><a href="#n17">exception.i</a>
<li><a href="#Library_nn17">exception.i</a>
</ul>
</ul>
<!-- 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.
Alternative libraries provide similar functionality. Please read this chapter
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.
When searching for files, directories are searched in the following order:
<p>
<ul>
<li>The current directory
<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>On Windows, SWIG also looks for the library relative to the location of <tt>swig.exe</tt>.
</ul>
<p>
<p>
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
for language-specific implementations of library files.
</p>
<p>
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.
@ -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
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
@ -93,11 +96,15 @@ this module is in generating pointers to primitive datatypes such as
<p>
<b><tt>%pointer_functions(type,name)</tt></b>
</p>
<blockquote>
Generates a collection of four functions for manipulating a pointer <tt>type *</tt>:
<p>
<tt>type *new_name()</tt>
</p>
<blockquote>
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.
@ -105,6 +112,8 @@ object is created using <tt>calloc()</tt>. In C++, <tt>new</tt> is used.
<p>
<tt>type *copy_name(type value)</tt>
</p>
<blockquote>
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
@ -113,18 +122,24 @@ object is created using <tt>calloc()</tt>. In C++, <tt>new</tt> is used.
<p>
<tt>type *delete_name(type *obj)</tt>
</p>
<blockquote>
Deletes an object type <tt>type</tt>.
</blockquote>
<p>
<tt>void name_assign(type *obj, type value)</tt>
</p>
<blockquote>
Assigns <tt>*obj = value</tt>.
</blockquote>
<p>
<tt>type name_value(type *obj)</tt>
</p>
<blockquote>
Returns the value of <tt>*obj</tt>.
</blockquote>
@ -151,18 +166,19 @@ Now, in Python:
<blockquote>
<pre>
>>> import example
>>> c = example.new_intp() # Create an "int" for storing result
>>> example.add(3,4,c) # Call function
>>> example.intp_value(c) # Dereference
&gt;&gt;&gt; import example
&gt;&gt;&gt; c = example.new_intp() # Create an "int" for storing result
&gt;&gt;&gt; example.add(3,4,c) # Call function
&gt;&gt;&gt; example.intp_value(c) # Dereference
7
>>> example.delete_intp(c) # Delete
&gt;&gt;&gt; example.delete_intp(c) # Delete
</pre>
</blockquote>
<p>
<p>
<b><tt>%pointer_class(type,name)</tt></b>
</p>
<blockquote>
Wraps a pointer of <tt>type *</tt> inside a class-based interface. This
interface is as follows:
@ -190,10 +206,14 @@ the "class" may be transparently passed to any function that expects the pointe
<p>
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.
</p>
<p>
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.
</p>
</blockquote>
@ -216,10 +236,10 @@ Now, in Python (using proxy classes)
<blockquote>
<pre>
>>> import example
>>> c = example.intp() # Create an "int" for storing result
>>> example.add(3,4,c) # Call function
>>> c.value() # Dereference
&gt;&gt;&gt; import example
&gt;&gt;&gt; c = example.intp() # Create an "int" for storing result
&gt;&gt;&gt; example.add(3,4,c) # Call function
&gt;&gt;&gt; c.value() # Dereference
7
</pre>
</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
(destruction of the pointer object destroys the underlying object).
<p>
<p>
<b><tt>%pointer_cast(type1, type2, name)</tt></b>
</p>
<blockquote>
Creates a casting function that converts <tt>type1</tt> to <tt>type2</tt>. The name of the function is <tt>name</tt>.
For example:
@ -247,11 +268,13 @@ In this example, the function <tt>int_to_uint()</tt> would be used to cast type
<p>
<b>Note:</b> None of these macros can be used to safely work with strings (<tt>char *</tt> or <tt>char **</tt>).
</p>
<P>
<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.
@ -261,11 +284,15 @@ raw C array data.
<p>
<b><tt>%array_functions(type,name)</tt></b>
</p>
<blockquote>
Creates four functions.
<p>
<tt>type *new_name(int nelements)</tt>
</p>
<blockquote>
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.
@ -273,18 +300,24 @@ Creates a new array of objects of type <tt>type</tt>. In C, the array is alloc
<p>
<tt>type *delete_name(type *ary)</tt>
</p>
<blockquote>
Deletes an array. In C, <tt>free()</tt> is used. In C++, <tt>delete []</tt> is used.
</blockquote>
<p>
<tt>type name_getitem(type *ary, int index)</tt>
</p>
<blockquote>
Returns the value <tt>ary[index]</tt>.
</blockquote>
<p>
<tt>void name_setitem(type *ary, int index, type value)</tt>
</p>
<blockquote>
Assigns <tt>ary[index] = value</tt>.
</blockquote>
@ -296,6 +329,7 @@ should not correspond to any other name used in the interface file.
<p>
Here is an example of <tt>%array_functions()</tt>. Suppose you had a
function like this:
</p>
<blockquote>
<pre>
@ -333,8 +367,6 @@ delete_doubleArray(a) # Destroy array
</pre>
</blockquote>
<p>
<p>
<b><tt>%array_class(type,name)</tt></b>
<blockquote>
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>
When combined with proxy classes, the <tt>%array_class()</tt> macro can be especially useful.
For example:
</p>
<blockquote>
<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
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.
</p>
<p>
<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>.
</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
@ -405,6 +440,8 @@ This module defines macros for wrapping the low-level C memory allocation functi
<p>
<b><tt>%malloc(type [,name=type])</tt></b>
</p>
<blockquote>
Creates a wrapper around <tt>malloc()</tt> with the following prototype:
<blockquote><pre>
@ -418,6 +455,8 @@ is not a valid identifier (e.g., "<tt>int *</tt>", "<tt>double **</tt>", etc.).
<p>
<b><tt>%calloc(type [,name=type])</tt></b>
</p>
<blockquote>
Creates a wrapper around <tt>calloc()</tt> with the following prototype:
<blockquote><pre>
@ -429,6 +468,8 @@ If <tt>type</tt> is <tt>void</tt>, then the size parameter <tt>sz</tt> is requir
<p>
<b><tt>%realloc(type [,name=type])</tt></b>
</p>
<blockquote>
Creates a wrapper around <tt>realloc()</tt> with the following prototype:
<blockquote><pre>
@ -442,6 +483,8 @@ it holds 100 integers.
<p>
<b><tt>%free(type [,name=type])</tt></b>
</p>
<blockquote>
Creates a wrapper around <tt>free()</tt> with the following prototype:
<blockquote><pre>
@ -452,6 +495,8 @@ void free_<em>name</em>(<em>type</em> *ptr);
<p>
<b><tt>%sizeof(type [,name=type])</tt></b>
</p>
<blockquote>
Creates the constant:
<blockquote><pre>
@ -462,12 +507,15 @@ Creates the constant:
<p>
<b><tt>%allocators(type [,name=type])</tt></b>
</p>
<blockquote>
Generates wrappers for all five of the above operations.
</blockquote>
<p>
Here is a simple example that illustrates the use of these macros:
</p>
<blockquote>
<pre>
@ -489,27 +537,27 @@ Now, in a script:
<blockquote>
<pre>
>>> from example import *
>>> a = malloc_int()
>>> a
&gt;&gt;&gt; from example import *
&gt;&gt;&gt; a = malloc_int()
&gt;&gt;&gt; a
'_000efa70_p_int'
>>> free_int(a)
>>> b = malloc_intp()
>>> b
&gt;&gt;&gt; free_int(a)
&gt;&gt;&gt; b = malloc_intp()
&gt;&gt;&gt; b
'_000efb20_p_p_int'
>>> free_intp(b)
>>> c = calloc_double(50)
>>> c
&gt;&gt;&gt; free_intp(b)
&gt;&gt;&gt; c = calloc_double(50)
&gt;&gt;&gt; c
'_000fab98_p_double'
>>> c = realloc_double(100000)
>>> free_double(c)
>>> print sizeof_double
&gt;&gt;&gt; c = realloc_double(100000)
&gt;&gt;&gt; free_double(c)
&gt;&gt;&gt; print sizeof_double
8
>>>
&gt;&gt;&gt;
</pre>
</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
@ -520,6 +568,8 @@ in order for this to work.
<p>
<b><tt>char *cdata(void *ptr, int nbytes)</tt></b>
</p>
<blockquote>
Converts <tt>nbytes</tt> of data at <tt>ptr</tt> into a string. <tt>ptr</tt> can be any
pointer.
@ -527,6 +577,8 @@ pointer.
<p>
<b><tt>void memmove(void *ptr, char *s)</tt></b>
</p>
<blockquote>
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
@ -551,18 +603,18 @@ Python example:
<blockquote>
<pre>
>>> a = intArray(10)
>>> for i in range(0,10):
&gt;&gt;&gt; a = intArray(10)
&gt;&gt;&gt; for i in range(0,10):
... a[i] = i
>>> b = cdata(a,40)
>>> b
&gt;&gt;&gt; b = cdata(a,40)
&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\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\t'
>>> c = intArray(10)
>>> memmove(c,b)
>>> print c[4]
&gt;&gt;&gt; c = intArray(10)
&gt;&gt;&gt; memmove(c,b)
&gt;&gt;&gt; print c[4]
4
>>>
&gt;&gt;&gt;
</pre>
</blockquote>
@ -570,6 +622,8 @@ Since the size of data is not always known, the following macro is also defined:
<p>
<b><tt>%cdata(type [,name=type])</tt></b>
</p>
<blockquote>
Generates the following function for extracting C data for a given type.
<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.
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
@ -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
morality. The modules in this section provide basic functionality
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:
@ -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
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.
</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,
@ -660,14 +716,14 @@ Now, in the target language, you can use binary string data like this:
<blockquote>
<pre>
>>> s = "H\x00\x15eg\x09\x20"
>>> parity(s,0)
&gt;&gt;&gt; s = "H\x00\x15eg\x09\x20"
&gt;&gt;&gt; parity(s,0)
</pre>
</blockquote>
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,
@ -687,6 +743,7 @@ into a string object and the old contents ignored.
<p>
To fix the memory leak, use the <tt>%newobject</tt> directive.
</p>
<blockquote>
<pre>
@ -698,7 +755,7 @@ char *foo();
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
@ -731,9 +788,12 @@ involving bounds checking).
<p>
The macros defined in this module all expand to various combinations of
typemaps. Therefore, the same pattern matching rules and ideas apply.
</p>
<p>
<b>%cstring_bounded_output(parm, maxsize)</b>
</p>
<blockquote>
Turns parameter <tt><em>parm</em></tt> into an output value. The
output string is assumed to be NULL-terminated and smaller than
@ -751,9 +811,9 @@ In the target language:
<blockquote>
<pre>
>>> get_path()
&gt;&gt;&gt; get_path()
/home/beazley/packages/Foo/Bar
>>>
&gt;&gt;&gt;
</pre>
</blockquote>
@ -768,6 +828,8 @@ bytes are written, your program will crash with a buffer overflow!</b>
<p>
<b>%cstring_chunk_output(parm, chunksize)</b>
</p>
<blockquote>
Turns parameter <tt><em>parm</em></tt> into an output value. The
output string is always <tt><em>chunksize</em></tt> and may contain
@ -785,9 +847,9 @@ In the target language:
<blockquote>
<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'
>>>
&gt;&gt;&gt;
</pre>
</blockquote>
@ -801,6 +863,8 @@ bytes are written, your program will crash with a buffer overflow!</b>
<p>
<b>%cstring_bounded_mutable(parm, maxsize)</b>
</p>
<blockquote>
Turns parameter <tt><em>parm</em></tt> into a mutable string argument.
The input string is assumed to be NULL-terminated and smaller than
@ -819,9 +883,9 @@ In the target language:
<blockquote>
<pre>
>>> make_upper("hello world")
&gt;&gt;&gt; make_upper("hello world")
'HELLO WORLD'
>>>
&gt;&gt;&gt;
</pre>
</blockquote>
@ -837,6 +901,8 @@ written, your program will crash with a buffer overflow!</b>
<p>
<b>%cstring_mutable(parm [, expansion])</b>
</p>
<blockquote>
Turns parameter <tt><em>parm</em></tt> into a mutable string argument.
The input string is assumed to be NULL-terminated. An optional
@ -861,11 +927,11 @@ In the target language:
<blockquote>
<pre>
>>> make_upper("hello world")
&gt;&gt;&gt; make_upper("hello world")
'HELLO WORLD'
>>> attach_header("Hello world")
&gt;&gt;&gt; attach_header("Hello world")
'header: Hello world'
>>>
&gt;&gt;&gt;
</pre>
</blockquote>
@ -884,6 +950,8 @@ bytes, then the program will crash with a buffer overflow!</b>
<p>
<b>%cstring_output_maxsize(parm, maxparm)</b>
</p>
<blockquote>
This macro is used to handle bounded character output functions where
both a <tt>char *</tt> and a maximum length parameter are provided.
@ -902,9 +970,9 @@ In the target language:
<blockquote>
<pre>
>>> get_path(1024)
&gt;&gt;&gt; get_path(1024)
'/home/beazley/Packages/Foo/Bar'
>>>
&gt;&gt;&gt;
</pre>
</blockquote>
@ -918,6 +986,8 @@ into that buffer and returned as a string object.
<p>
<b>%cstring_output_withsize(parm, maxparm)</b>
</p>
<blockquote>
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,
@ -938,11 +1008,11 @@ In the target language:
<blockquote>
<pre>
>>> get_data(1024)
&gt;&gt;&gt; get_data(1024)
'x627388912'
>>> get_data(1024)
&gt;&gt;&gt; get_data(1024)
'xyzzy'
>>>
&gt;&gt;&gt;
</pre>
</blockquote>
@ -954,6 +1024,8 @@ how much data is actually returned by changing the value of the <tt>maxparm</tt>
<p>
<b>%cstring_output_allocate(parm, release)</b>
</p>
<blockquote>
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:
@ -983,9 +1055,9 @@ In the target language:
<blockquote>
<pre>
>>> foo()
&gt;&gt;&gt; foo()
'Hello world\n'
>>>
&gt;&gt;&gt;
</pre>
</blockquote>
</blockquote>
@ -993,6 +1065,8 @@ In the target language:
<p>
<b>%cstring_output_allocate_size(parm, szparm, release)</b>
</p>
<blockquote>
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:
@ -1024,9 +1098,9 @@ In the target language:
<blockquote>
<pre>
>>> foo()
&gt;&gt;&gt; foo()
'\xa9Y:\xf6\xd7\xe1\x87\xdbH;y\x97\x7f"\xd3\x99\x14V\xec\x06\xea\xa2\x88'
>>>
&gt;&gt;&gt;
</pre>
</blockquote>
@ -1053,30 +1127,31 @@ void my_get_data(char **result, int *len) {
<b>Comments:</b>
<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.
</li>
<p>
<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.
</li>
<P>
<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>.
</li>
<p>
<li>Rather than manipulating <tt>char *</tt> directly, you might consider using a special string
structure or class instead.
</li>
</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.
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.
<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>
@ -1088,7 +1163,7 @@ objects to and from strings in the target scripting language. For example:
%include "std_string.i"
std::string foo();
void bar(const std::string &x);
void bar(const std::string &amp;x);
</pre>
</blockquote>
@ -1102,12 +1177,13 @@ bar("Hello World"); # Pass string as std::string
</blockquote>
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.
<p>
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:
</p>
<blockquote>
<pre>
@ -1117,14 +1193,14 @@ it with a typedef, make sure you include those declarations in your interface.
using namespace std;
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>
</blockquote>
<b>Note:</b> The <tt>std_string</tt> library is incompatible with Perl on some platforms.
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.
@ -1137,66 +1213,66 @@ instantiate different versions of <tt>vector</tt> for the types that you want to
%include "std_vector.i"
namespace std {
%template(vectori) vector&lt;int>;
%template(vectord) vector&lt;double>;
%template(vectori) vector&lt;int&gt;;
%template(vectord) vector&lt;double&gt;;
};
</pre>
</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>
<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
currently a subset of the real STL vector class.
</li>
<p>
<li>Input typemaps are defined for <tt>vector&lt;X></tt>, <tt>const vector&lt;X> &</tt>, and
<tt>const vector&lt;X> *</tt>. For each of these, a pointer <tt>vector&lt;X> *</tt> may be passed or
<li>Input typemaps are defined for <tt>vector&lt;X&gt;</tt>, <tt>const vector&lt;X&gt; &amp;</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
a native list object in the target language.
</li>
<P>
<li>An output typemap is defined for <tt>vector&lt;X></tt>. In this case, the values in the
<li>An output typemap is defined for <tt>vector&lt;X&gt;</tt>. In this case, the values in the
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> *</tt>
<li>For all other variations of the type, the wrappers expect to receive a <tt>vector&lt;X&gt; *</tt>
object in the usual manner.
</li>
<P>
<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
may be defined. This depends on the target language.
</li>
</ul>
<p>
To illustrate the use of this library, consider the following functions:
<blockquote>
<pre>
/* File : example.h */
#include &lt;vector>
#include &lt;algorithm>
#include &lt;functional>
#include &lt;numeric>
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;functional&gt;
#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();
}
std::vector&lt;double> half(const std::vector&lt;double>&amp; v) {
std::vector&lt;double> w(v);
std::vector&lt;double&gt; half(const std::vector&lt;double&gt;&amp; v) {
std::vector&lt;double&gt; w(v);
for (unsigned int i=0; i&lt;w.size(); i++)
w[i] /= 2.0;
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::bind2nd(std::divides&lt;double>(),2.0));
std::bind2nd(std::divides&lt;double&gt;(),2.0));
}
</pre>
</blockquote>
@ -1213,8 +1289,8 @@ To wrap with SWIG, you might write the following:
%include "std_vector.i"
// Instantiate templates used by example
namespace std {
%template(IntVector) vector&lt;int>;
%template(DoubleVector) vector&lt;double>;
%template(IntVector) vector&lt;int&gt;;
%template(DoubleVector) vector&lt;double&gt;;
}
// Include the header file with above prototypes
@ -1226,38 +1302,38 @@ Now, to illustrate the behavior in the scripting interpreter, consider this Pyth
<blockquote>
<pre>
>>> from example import *
>>> iv = IntVector(4) # Create an vector&lt;int>
>>> for i in range(0,4):
&gt;&gt;&gt; from example import *
&gt;&gt;&gt; iv = IntVector(4) # Create an vector&lt;int&gt;
&gt;&gt;&gt; for i in range(0,4):
... iv[i] = i
>>> average(iv) # Call method
&gt;&gt;&gt; average(iv) # Call method
1.5
>>> average([0,1,2,3]) # Call with list
&gt;&gt;&gt; average([0,1,2,3]) # Call with list
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)
>>> halve_in_place([1,2,3]) # Oops
&gt;&gt;&gt; halve_in_place([1,2,3]) # Oops
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
>>> dv = DoubleVector(4)
>>> for i in range(0,4):
&gt;&gt;&gt; dv = DoubleVector(4)
&gt;&gt;&gt; for i in range(0,4):
... dv[i] = i
>>> halve_in_place(dv) # Ok
>>> for i in dv:
&gt;&gt;&gt; halve_in_place(dv) # Ok
&gt;&gt;&gt; for i in dv:
... print i
...
0.0
0.5
1.0
1.5
>>> dv[20] = 4.5
&gt;&gt;&gt; dv[20] = 4.5
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__
def __setitem__(*args): return apply(examplec.DoubleVector___setitem__,args)
IndexError: vector index out of range
>>>
&gt;&gt;&gt;
</pre>
</blockquote>
@ -1269,13 +1345,13 @@ make sure you include the appropriate <tt>using</tt> or typedef directives. For
%include "std_vector.i"
namespace std {
%template(IntVector) vector&lt;int>;
%template(IntVector) vector&lt;int&gt;;
}
using namespace std;
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>
</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
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.
</p>
<p>
<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.
</p>
<p>
<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
@ -1304,6 +1383,8 @@ exception in the target language.
<p>
<b><tt>SWIG_exception(int code, const char *message)</tt></b>
</p>
<blockquote>
Raises an exception in the target language. <tt>code</tt> is one of the following symbolic
constants:
@ -1336,14 +1417,14 @@ For example:
try {
$action
} 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>
</blockquote>
<p><hr>
<hr>
<address>SWIG 1.3 - Last Modified : May 29, 2002</address>
</body>
</html>

View file

@ -4,31 +4,31 @@
<title>SWIG and Modula-3</title>
</head>
<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 -->
<ul>
<li><a href="#n2">Overview</a>
<li><a href="#n3">Conception</a>
<li><a href="#modula3_overview">Overview</a>
<li><a href="#conception">Conception</a>
<ul>
<li><a href="#n4">Interfaces to C libraries</a>
<li><a href="#n5">Interfaces to C++ libraries</a>
<li><a href="#n6">No plan?</a>
<li><a href="#cinterface">Interfaces to C libraries</a>
<li><a href="#noplan">Interfaces to C++ libraries</a>
<li><a href="#cppinterface">No plan?</a>
</ul>
<li><a href="#n7">Preliminaries</a>
<li><a href="#preliminaries">Preliminaries</a>
<ul>
<li><a href="#n8">Compilers</a>
<li><a href="#n9">Additional Commandline Options</a>
<li><a href="#compilers">Compilers</a>
<li><a href="#commandline">Additional Commandline Options</a>
</ul>
<li><a href="#n10">Modula-3 typemaps</a>
<li><a href="#modula3_typemaps">Modula-3 typemaps</a>
<ul>
<li><a href="#n11">Inputs and outputs</a>
<li><a href="#n12">Subranges, Enumerations, Sets</a>
<li><a href="#n13">Objects</a>
<li><a href="#n14">Imports</a>
<li><a href="#n15">Exceptions</a>
<li><a href="#n16">Pragmas</a>
<li><a href="#n17">Example</a>
<li><a href="#n18">Remarks</a>
<li><a href="#inoutparam">Inputs and outputs</a>
<li><a href="#ordinals">Subranges, Enumerations, Sets</a>
<li><a href="#class">Objects</a>
<li><a href="#imports">Imports</a>
<li><a href="#exceptions">Exceptions</a>
<li><a href="#swig_pragmas">Pragmas</a>
<li><a href="#typemap_example">Example</a>
<li><a href="#remarks">Remarks</a>
</ul>
</ul>
<!-- INDEX -->
@ -38,12 +38,11 @@
This chapter describes SWIG's support of
<a href="http://www.m3.org/">Modula-3</a>.
You should be familiar with the
<a href="SWIG.html">basics</a>
<a href="SWIG.html#SWIG">basics</a>
of SWIG,
especially typemaps.
<a name="overview"></a>
<a name="n2"></a><H2>18.1 Overview</H2>
<H2><a name="modula3_overview"></a>20.1 Overview</H2>
<p>
@ -52,6 +51,8 @@ Many features are still not designed satisfyingly
and I need more discussion about the odds and ends.
The Modula-3 generator was already useful for interfacing
to the libraries
</p>
<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/plplot/">
PLPlot
</a>
@ -66,9 +67,9 @@ FFTW
The following introduction may help you
when you are uncertain about using
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>
@ -80,6 +81,7 @@ to make programming life easier
by hiding machine internals from the programmer
there are several aspects of todays scripting languages
that are unfavourable in my opinion.
</p>
<p>
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,
are not advantages of the language itself
but can be provided by function libraries.
</p>
<a name="whymodula3"></a>
<a name="n4"></a><DISABLED>18.1.2 Why Modula-3 ?</DISABLED>
@ -124,6 +126,7 @@ control three languages,
namely the preprocessor, C and ++,
Modula-3 is made in one go
and the language definition is really compact.
</p>
On the one hand Modula-3 can be safe
(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
I prefer Haskell (similar to OCAML) -
it's statically typed, too.
</p>
<a name="whycxx"></a>
<a name="n5"></a><DISABLED>18.1.3 Why C / C++ ?</DISABLED>
<p>
Although it is no problem to write Modula-3 programs
that performs as fast as 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.
Even more fortunately even non-C libraries may provide C header files.
This is where SWIG becomes helpful.
</p>
<a name="whycxx"></a>
<a name="n6"></a><DISABLED>18.1.4 Why SWIG ?</DISABLED>
<p>
The C headers and the possibility to interface to C libraries
still leaves the work for you
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
(garbage collecting, exceptions)
and the low level of the C libraries.
</p>
<p>
SWIG converts C headers to Modula-3 interfaces for you.
You could call the C functions without loss
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.
You should turn such work-arounds back to the Modula-3 way
otherwise you lose static safety and consistency.
</p>
<p>
@ -203,9 +205,10 @@ when a new library version is released.
You will realise that writing <b>good</b> SWIG interfaces
is very costly and it will only amortise
when considering evolving libraries.
</p>
<p>
Without SWIG you would probably never consider
to call C++ libraries from Modula-3.
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.
To make it complete you can hide the C interface
with Modula-3 classes and exceptions.
</p>
<p>
Although SWIG does the best it can do
it can only serve as a one-way strategy.
That means you can use C++ libraries
with Modula-3 (even with call back functions),
but it's certainly not possible to smoothly
integrate Modula-3 code into a C / C++ project.
</p>
-->
<a name="conception"></a>
<a name="n3"></a><H2>18.2 Conception</H2>
<H2><a name="conception"></a>20.2 Conception</H2>
<a name="cinterface"></a>
<a name="n4"></a><H3>18.2.1 Interfaces to C libraries</H3>
<H3><a name="cinterface"></a>20.2.1 Interfaces to C libraries</H3>
<p>
@ -249,7 +251,7 @@ All you have to do is to write pieces of Modula-3 code
that SWIG puts together.
</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>
<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
generates several files:
</p>
<table border>
<table border summary="Modula-3 generated files">
<tr>
<td>Module<tt>Raw.i3</tt></td>
<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
a redirected to C library functions:
<table>
<table summary="Modula-3 C library">
<tr>
<td align=center>
Modula-3 wrapper<br>
@ -347,8 +349,7 @@ a redirected to C library functions:
</table>
<a name="cppinterface"></a>
<a name="n5"></a><H3>18.2.2 Interfaces to C++ libraries</H3>
<H3><a name="noplan"></a>20.2.2 Interfaces to C++ libraries</H3>
<p>
@ -361,7 +362,7 @@ with a C interface.
Here's a scheme of how the function calls to Modula-3 wrappers
a redirected to C library functions:
<table>
<table summary="Modula-3 C++ library">
<tr>
<td align=center>
Modula-3 wrapper<br>
@ -400,6 +401,7 @@ a redirected to C library functions:
<p>
Wrapping C++ libraries arises additional problems:
</p>
<ul>
<li>
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.
</p>
<a name="cppinterface"></a>
<a name="n6"></a><H3>18.2.3 No plan?</H3>
<H3><a name="cppinterface"></a>20.2.3 No plan?</H3>
<p>
@ -468,12 +469,10 @@ and the principal type must be renamed (<tt>%typemap</tt>).
</p>
<a name="preliminaries"></a>
<a name="n7"></a><H2>18.3 Preliminaries</H2>
<H2><a name="preliminaries"></a>20.3 Preliminaries</H2>
<a name="compilers"></a>
<a name="n8"></a><H3>18.3.1 Compilers</H3>
<H3><a name="compilers"></a>20.3.1 Compilers</H3>
There are different Modula-3 compilers around:
@ -485,8 +484,7 @@ may do so.
For testing examples I used Critical Mass cm3.
<a name="commandline"></a>
<a name="n9"></a><H3>18.3.2 Additional Commandline Options</H3>
<H3><a name="commandline"></a>20.3.2 Additional Commandline Options</H3>
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
when writing SWIG interface files.
<table>
<table summary="Modula-3 specific options">
<tr>
<th>Modula-3 specific options</th>
</tr>
@ -560,12 +558,10 @@ Instead generate templates for some basic typemaps.
</tr>
</table>
<a name="typemaps"></a>
<a name="n10"></a><H2>18.4 Modula-3 typemaps</H2>
<H2><a name="modula3_typemaps"></a>20.4 Modula-3 typemaps</H2>
<a name="inoutparam"></a>
<a name="n11"></a><H3>18.4.1 Inputs and outputs</H3>
<H3><a name="inoutparam"></a>20.4.1 Inputs and outputs</H3>
<p>
@ -614,7 +610,7 @@ consist of the following parts:
<li>Return values.</li>
</ul>
<table border>
<table border summary="Modula-3 typemaps">
<tr>
<th>Typemap</th>
<th>Example</th>
@ -654,21 +650,21 @@ consist of the following parts:
</tr>
<tr>
<td>m3wrapinname</td>
<td><tt></tt></td>
<td></td>
<td>
New name of the input argument.
</td>
</tr>
<tr>
<td>m3wrapintype</td>
<td><tt></tt></td>
<td></td>
<td>
Modula-3 type of the input argument.
</td>
</tr>
<tr>
<td>m3wrapindefault</td>
<td><tt></tt></td>
<td></td>
<td>
Default value of the input argument
</td>
@ -682,14 +678,14 @@ consist of the following parts:
</tr>
<tr>
<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>
Check the integrity of the input value.
</td>
</tr>
<tr>
<td>m3wrapoutname</td>
<td><tt></tt></td>
<td></td>
<td>
Name of the <tt>RECORD</tt> field to be used for returning multiple values.
This applies to referential output arguments that shall be turned
@ -698,56 +694,56 @@ consist of the following parts:
</tr>
<tr>
<td>m3wrapouttype</td>
<td><tt></tt></td>
<td></td>
<td>
Type of the value that is returned instead of a referential output argument.
</td>
</tr>
<tr>
<td>m3wrapoutconv</td>
<td><tt></tt></td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapoutcheck</td>
<td><tt></tt></td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretraw</td>
<td><tt></tt></td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretname</td>
<td><tt></tt></td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wraprettype</td>
<td><tt></tt></td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretvar</td>
<td><tt></tt></td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretconv</td>
<td><tt></tt></td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretcheck</td>
<td><tt></tt></td>
<td></td>
<td>
</td>
</tr>
@ -764,16 +760,13 @@ consist of the following parts:
</table>
<a name="ordinals"></a>
<a name="n12"></a><H3>18.4.2 Subranges, Enumerations, Sets</H3>
<H3><a name="ordinals"></a>20.4.2 Subranges, Enumerations, Sets</H3>
<a name="class"></a>
<a name="n13"></a><H3>18.4.3 Objects</H3>
<H3><a name="class"></a>20.4.3 Objects</H3>
<a name="imports"></a>
<a name="n14"></a><H3>18.4.4 Imports</H3>
<H3><a name="imports"></a>20.4.4 Imports</H3>
<p>
@ -806,8 +799,7 @@ IMPORT M3toC;
</pre>
<a name="exceptions"></a>
<a name="n15"></a><H3>18.4.5 Exceptions</H3>
<H3><a name="exceptions"></a>20.4.5 Exceptions</H3>
Modula-3 provides another possibility
@ -825,11 +817,10 @@ contains code that may raise the exceptions <tt>OSError.E</tt>
you should declare
<tt>%typemap("m3wrapinconv:throws") blah * %{OSError.E%}</tt>.
<a name="swig_pragmas"></a>
<a name="n16"></a><H3>18.4.6 Pragmas</H3>
<H3><a name="swig_pragmas"></a>20.4.6 Pragmas</H3>
<table border>
<table border summary="Modula-3 pragmas">
<tr>
<td>unsafe</td>
<td><tt>%pragma(modula3) unsafe="true";</tt></td>
@ -844,8 +835,7 @@ you should declare
</tr>
</table>
<a name="typemap_example"></a>
<a name="n17"></a><H3>18.4.7 Example</H3>
<H3><a name="typemap_example"></a>20.4.7 Example</H3>
The generation of wrappers in Modula-3 needs very fine control
@ -871,7 +861,7 @@ where almost everything is generated by a typemap:
BEGIN
TRY
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");
END;
<I> (* m3wrapretraw m3wrapargraw *)</I>
@ -887,8 +877,7 @@ where almost everything is generated by a typemap:
END Name;
</pre></blockquote>
<a name="remarks"></a>
<a name="n18"></a><H3>18.4.8 Remarks</H3>
<H3><a name="remarks"></a>20.4.8 Remarks</H3>
<ul>

View file

@ -5,13 +5,14 @@
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>14 Working with Modules</H1>
<H1><a name="Modules"></a>15 Working with Modules</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">The SWIG runtime code</a>
<li><a href="#n3">Compiling Multiple SWIG modules</a>
<li><a href="#n4">A word of caution about static libraries</a>
<li><a href="#n5">References</a>
<li><a href="#Modules_nn2">The SWIG runtime code</a>
<li><a href="#Modules_nn3">Compiling Multiple SWIG modules</a>
<li><a href="#Modules_nn4">A word of caution about static libraries</a>
<li><a href="#Modules_nn5">References</a>
<li><a href="#Modules_nn6">Reducing the wrapper file size</a>
</ul>
<!-- INDEX -->
@ -28,8 +29,9 @@ target language interface when it is broken up into smaller pieces.
<p>
This chapter describes the problem of using SWIG in programs
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
@ -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
where SWIG must collect and share information about inheritance
relationships that cross module boundaries.
</p>
<p>
To solve the problem of sharing information across modules, the
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.
</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
@ -67,10 +71,12 @@ there are two approaches you can take:
<p>
<b>Option 1:</b> Designate one module to provide the runtime code
</p>
<p>
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:
</p>
<blockquote>
<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
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.
</p>
<p>
<b>Option 2: Build a runtime library</b>
</p>
<p>
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
just the %module directive, for example:
</p>
<blockquote>
<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 the modules are imported. Moreover, since all of the modules are linked against the same runtime
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
@ -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
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
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.
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.
</p>
<p/>
<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.
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.
<p/>
<p>
<b>-fvirtual</b><br>
This command line option will remove the generation of superfluous virtual method wrappers.
Consider the following inheritance hierarchy:
</p>
<blockquote>
<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
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>
</body>

View file

@ -6,47 +6,47 @@
</head>
<body bgcolor="#ffffff">
<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 -->
<ul>
<li><a href="#n2">Preliminaries</a>
<li><a href="#Ocaml_nn2">Preliminaries</a>
<ul>
<li><a href="#n3">Running SWIG</a>
<li><a href="#n4">Compiling the code</a>
<li><a href="#n5">The camlp4 module</a>
<li><a href="#n6">Using your module</a>
<li><a href="#n7">Compilation problems and compiling with C++</a>
<li><a href="#Ocaml_nn3">Running SWIG</a>
<li><a href="#Ocaml_nn4">Compiling the code</a>
<li><a href="#Ocaml_nn5">The camlp4 module</a>
<li><a href="#Ocaml_nn6">Using your module</a>
<li><a href="#Ocaml_nn7">Compilation problems and compiling with C++</a>
</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>
<li><a href="#n9">The generated module</a>
<li><a href="#n10">Enums</a>
<li><a href="#n11">Arrays</a>
<li><a href="#Ocaml_nn9">The generated module</a>
<li><a href="#Ocaml_nn10">Enums</a>
<li><a href="#Ocaml_nn11">Arrays</a>
<ul>
<li><a href="#n12">Simple types of bounded arrays</a>
<li><a href="#n13">Complex and unbounded arrays</a>
<li><a href="#n14">Using an object</a>
<li><a href="#n15">Example typemap for a function taking float * and int</a>
<li><a href="#Ocaml_nn12">Simple types of bounded arrays</a>
<li><a href="#Ocaml_nn13">Complex and unbounded arrays</a>
<li><a href="#Ocaml_nn14">Using an object</a>
<li><a href="#Ocaml_nn15">Example typemap for a function taking float * and int</a>
</ul>
<li><a href="#n16">C++ Classes</a>
<li><a href="#Ocaml_nn16">C++ Classes</a>
<ul>
<li><a href="#n17">STL vector and string Example</a>
<li><a href="#n18">C++ Class Example</a>
<li><a href="#n19">Compiling the example</a>
<li><a href="#n20">Sample Session</a>
<li><a href="#Ocaml_nn17">STL vector and string Example</a>
<li><a href="#Ocaml_nn18">C++ Class Example</a>
<li><a href="#Ocaml_nn19">Compiling the example</a>
<li><a href="#Ocaml_nn20">Sample Session</a>
</ul>
<li><a href="#n21">Director Classes</a>
<li><a href="#Ocaml_nn21">Director Classes</a>
<ul>
<li><a href="#n22">Director Introduction</a>
<li><a href="#n23">Overriding Methods in Ocaml</a>
<li><a href="#n24">Director Usage Example</a>
<li><a href="#n25">Creating director objects</a>
<li><a href="#n26">Typemaps for directors, <tt>directorin, directorout, directorargout</tt></a>
<li><a href="#n27"><tt>directorin</tt> typemap</a>
<li><a href="#n28"><tt>directorout</tt> typemap</a>
<li><a href="#n29"><tt>directorargout</tt> typemap</a>
<li><a href="#Ocaml_nn22">Director Introduction</a>
<li><a href="#Ocaml_nn23">Overriding Methods in Ocaml</a>
<li><a href="#Ocaml_nn24">Director Usage Example</a>
<li><a href="#Ocaml_nn25">Creating director objects</a>
<li><a href="#Ocaml_nn26">Typemaps for directors, <tt>directorin, directorout, directorargout</tt></a>
<li><a href="#Ocaml_nn27"><tt>directorin</tt> typemap</a>
<li><a href="#Ocaml_nn28"><tt>directorout</tt> typemap</a>
<li><a href="#Ocaml_nn29"><tt>directorargout</tt> typemap</a>
</ul>
<li><a href="#n30">Exceptions</a>
<li><a href="#Ocaml_nn30">Exceptions</a>
</ul>
</ul>
<!-- 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>.
</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,
@ -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
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
@ -99,7 +99,9 @@ will be loaded dynamically. This has only been tested on Linux so far.
option.
<blockquote>
<pre>%swig -ocaml example.i</pre>
<pre>
%swig -ocaml example.i
</pre>
</blockquote>
<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
(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>)
separately. In addition to aggregating common SWIG functionality, the Swig
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
SWIG interface like:
<p> </p>
</p>
<blockquote>
<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 example.mli
% ocamlc -c example.ml
</blockquote>
</pre>
</blockquote>
<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
in C++ mode, you must: </p>
<blockquote>
<pre>% cp example_wrap.cxx example_wrap.cxx.c<br>% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c<br>% ...<br></pre>
</blockquote>
<pre>
% 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
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
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>"ocamlc -I `camlp4 -where` -pp 'camlp4o pa_extend.cmo q_MLast.cmo' -c swigp4.ml"</tt>
</p>
<p>
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
module is written to work with generated SWIG interfaces, and probably isn't
great to use with anything else.
</p>
<p>
Here are the main rewriting rules:
<p>
<table border="1">
</p>
<table border="1" summary="Rewriting rules">
<tr><th>Input</th><th>Rewritten to</th></tr>
<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>
<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>
object <i>'binop</i> argument as in<br>
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>
<tr><td>
<b>Smart pointer access like this</b><br>
object '-> method ( args )<br>
object '-&gt; method ( args )<br>
</td><td>
(invoke (invoke object "->" C_void))
(invoke (invoke object "-&gt;" C_void))
</td></tr>
<tr><td>
<b>Invoke syntax</b><br>
@ -211,37 +223,47 @@ let b = C_string (getenv "PATH")
</td></tr>
</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.
</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 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
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.
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
members of the c_obj type:
</p>
<p>
In the code as seen by the typemap
writer, there is a value, swig_result, that always contains 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
objective caml.<br>
</p>
<blockquote><pre>
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>
</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
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
appended. Upon return to caml space, the fnhelper function
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
pointers for C purposes, even using them to construct simple objects
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
C_obj. It allows you to wrap any type of thing you like as an
object using the same mechanism that the ocaml module
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>
You should only construct values using objective caml, or using the
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,
value items pass through directly, but you must make your own type
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
module to be generated. If you specified `<tt>%module example</tt>',
then your Ocaml code will be accessible in the module Example. The
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 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.
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
C wrapper file, before any function definitions.</td></tr>
<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>
<tr><td>"classtemplate"</td><td>The "classtemplate" place is special because
it describes the output SWIG will generate for class definitions.
</td></tr>
</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
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
@ -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
enum_to_int and int_to_enum functions take an enum type label as an
argument. Example:
<p>
</p>
<blockquote><pre>
%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 };
</pre></blockquote>
<p>
The output mli contains:
<p>
</p>
<blockquote><pre>
type c_enum_type = [
`unknown
@ -387,7 +424,8 @@ val enum_to_int c_enum_type -&gt; c_obj -&gt; c_obj
</blockquote>
So it's possible to do this:
<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
Objective Caml version 3.04
@ -401,12 +439,10 @@ val x : Enum_test.c_obj = C_enum `a
</pre>
</blockquote>
<p> </p>
<a name="n11"></a><H3>19.2.3 Arrays</H3>
<H3><a name="Ocaml_nn11"></a>21.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>
@ -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
some of the macros provided (but not included by default) with the SWIG
distribution.
</p>
<p>
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.
</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>
@ -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.
</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>
@ -453,7 +490,7 @@ Consider writing an object when the ending condition of your array is complex,
such as using a required centinel, etc.
</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>
@ -465,11 +502,12 @@ argument is the length of the array passed from ocaml, making passing an array
into this type of function convenient.
</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>
%module tarray
%{
#include <stdio.h>
#include &lt;stdio.h&gt;
void printfloats( float *tab, int len ) {
int i;
@ -503,7 +541,7 @@ void printfloats( float *tab, int len );
</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
@ -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
to any other operators an object might have, certain builtin ones are
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>"&amp;"</td><td>Return an ordinary C_ptr value representing this
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
the underlying pointer, so using create_[x]_from_ptr alters the
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
@ -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
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>
%module example
%{
@ -567,12 +606,17 @@ namespace std {
</pre></td></tr>
<tr><td><font size="-1"><i>This example is in Examples/ocaml/stl
</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
after making a toplevel (make toplevel). This example uses the camlp4
module.
</p>
<blockquote><pre>
bash-2.05a$ ./example_top
@ -583,27 +627,27 @@ bash-2.05a$ ./example_top
# open Swig ;;
# open Example ;;
# let x = new_StringVector '() ;;
val x : Example.c_obj = C_obj <fun>
# x -> ":methods" () ;;
val x : Example.c_obj = C_obj &lt;fun&gt;
# x -&gt; ":methods" () ;;
- : Example.c_obj =
C_list
[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 "~"; C_string "&"; C_string ":parents"; C_string ":classof";
C_string "~"; C_string "&amp;"; C_string ":parents"; C_string ":classof";
C_string ":methods"]
# x -> push_back ("foo") ;;
# x -&gt; push_back ("foo") ;;
- : Example.c_obj = C_void
# x -> push_back ("bar") ;;
# x -&gt; push_back ("bar") ;;
- : Example.c_obj = C_void
# x -> push_back ("baz") ;;
# x -&gt; push_back ("baz") ;;
- : Example.c_obj = C_void
# x '[1] ;;
- : Example.c_obj = C_string "bar"
# x -> set (1,"spam") ;;
# x -&gt; set (1,"spam") ;;
- : Example.c_obj = C_void
# x '[1] ;;
- : 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)
done ;;
foo
@ -613,12 +657,13 @@ baz
#
</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:
<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>
%module qt
%{
@ -638,9 +683,9 @@ public:
void resize( int x, int y );
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>
@ -658,7 +703,7 @@ bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
-L$QTPATH/lib -cclib -lqt
</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>
@ -670,33 +715,40 @@ bash-2.05a$ ./qt_top
# open Swig ;;
# open Qt ;;
# 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) ;;
val hello : Qt.c_obj = C_obj <fun>
# hello -> resize (100,30) ;;
val hello : Qt.c_obj = C_obj &lt;fun&gt;
# hello -&gt; resize (100,30) ;;
- : Qt.c_obj = C_void
# hello -> show () ;;
# hello -&gt; show () ;;
- : Qt.c_obj = C_void
# a -> exec () ;;
</pre></blockquote><p>
# a -&gt; exec () ;;
</pre></blockquote>
<p>
Assuming you have a working installation of QT, you will see a window
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
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
the context of an application or utility framework.
</p>
<p>
You can turn on director classes by using an optional module argument like
this:
<pre><blockquote><p>
</p>
<blockquote><pre>
%module(directors="1")
...
@ -706,9 +758,9 @@ this:
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>
@ -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.
Note that calls to the underlying object do not invoke Ocaml code. You need
to handle that yourself.
</p>
<p>
<tt>new_derived_object</tt> receives your function, the function that creates
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'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.
</p>
<p>
In this example, I'll examine the objective caml code involved in providing
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>
<tr><td><pre>
open Swig
@ -745,14 +802,14 @@ open Example
let triangle_class pts ob meth args =
match meth with
"cover" ->
"cover" -&gt;
(match args with
C_list [ x_arg ; y_arg ] ->
C_list [ x_arg ; y_arg ] -&gt;
let xa = x_arg as float
and ya = y_arg as float in
(point_in_triangle pts xa ya) to bool
| _ -> raise (Failure "cover needs two double arguments."))
| _ -> (invoke ob) meth args ;;
| _ -&gt; raise (Failure "cover needs two double arguments."))
| _ -&gt; (invoke ob) meth args ;;
let triangle =
new_derived_object
@ -763,6 +820,7 @@ let triangle =
let _ = _draw_shape_coverage '(triangle, C_int 60, C_int 20) ;;
</pre></td></tr>
</table>
<p>
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.
@ -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
calls on your object from with ocaml code will always invoke C++ methods
even if they are overridden in ocaml.
</p>
<p>
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
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
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
program in C++.
<p>
<a name="n25"></a><H4>19.2.5.4 Creating director objects</H4>
</p>
<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:
<pre><blockquote><p>
<blockquote><pre>
let triangle =
new_derived_object
new_shape
(triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
'()
</p></blockquote></pre>
</pre></blockquote>
<p>
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
@ -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
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.
</p>
<p>
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
@ -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++
object from causing a core dump, as long as the object is destroyed
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>
@ -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
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.
</P>
<a name="n27"></a><H4>19.2.5.6 <tt>directorin</tt> typemap</H4>
</p>
<H4><a name="Ocaml_nn27"></a>21.2.5.6 <tt>directorin</tt> typemap</H4>
<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.
</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>
@ -852,11 +918,11 @@ for the same type, except when there are special requirements for object
ownership, etc.
</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>
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.
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
@ -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.
</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

File diff suppressed because it is too large Load diff

View file

@ -6,44 +6,50 @@
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>21 SWIG and PHP4</H1>
<H1><a name="Php"></a>23 SWIG and PHP4</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Preliminaries</a>
<li><a href="#n3">Building PHP4 Extensions</a>
<li><a href="#Php_nn2">Preliminaries</a>
<li><a href="#Php_nn3">Building PHP4 Extensions</a>
<ul>
<li><a href="#n4">Building a loadable extension</a>
<li><a href="#n5">Basic PHP4 interface</a>
<li><a href="#n6">Functions</a>
<li><a href="#n7">Global Variables</a>
<li><a href="#n8">Pointers </a>
<li><a href="#n9">Structures and C++ classes</a>
<li><a href="#n10">Constants</a>
<li><a href="#n11">Shadow classes</a>
<li><a href="#n12">Constructors and Destructers</a>
<li><a href="#n13">Static Member Variables</a>
<li><a href="#n14">PHP4 Pragmas</a>
<li><a href="#n15">Building extensions into php</a>
<li><a href="#n16">To be furthered...</a>
<li><a href="#Php_nn4">Building a loadable extension</a>
<li><a href="#Php_nn5">Basic PHP4 interface</a>
<li><a href="#Php_nn6">Functions</a>
<li><a href="#Php_nn7">Global Variables</a>
<li><a href="#Php_nn8">Pointers </a>
<li><a href="#Php_nn9">Structures and C++ classes</a>
<li><a href="#Php_nn10">Constants</a>
<li><a href="#Php_nn11">Shadow classes</a>
<li><a href="#Php_nn12">Constructors and Destructers</a>
<li><a href="#Php_nn13">Static Member Variables</a>
<li><a href="#Php_nn14">PHP4 Pragmas</a>
<li><a href="#Php_nn15">Building extensions into php</a>
<li><a href="#Php_nn16">To be furthered...</a>
</ul>
</ul>
<!-- INDEX -->
<p>
<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
still under development so some of the features below may not work properly
(or at all!.)
</p>
<p>
The PHP4 module has undergone a lot of changes recently affecting the
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
that shadow classes are implemented inside the php module in C++ instead
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
@ -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
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>
To build a PHP4 extension, run swig using the <tt>-php4</tt> option as follows :
</p>
<blockquote><pre>
swig -php4 example.i
</pre></blockquote>
<p>
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,
<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 module into PHP directly, you can specify the <tt>-phpfull</tt>
command line argument to swig.
</p>
<p>
The <tt>-phpfull</tt> will generate three extra files.
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
Makefile after substitutions. The third and final extra file, <tt>CREDITS</tt>
should contain the credits for the extension.
</p>
<p>
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
@ -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
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.
</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
<tt>phpize</tt> utility, or you can do it manually.
</p>
<p>
To build manually, use a compile string similar to this (different for each
OS):
</p>
<blockquote><pre>
cc -I.. $(PHPINC) -fpic -c example_wrap.c
cc -shared example_wrap.o -o libexample.so
</pre></blockquote>
<p>
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
@ -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. )
If you like SWIG can generate simple extra tests for libraries and header
files for you.
</p>
<blockquote><pre>
swig -php4 -phpfull -withlibs "xapian omquery" --withincs "om.h"
</pre></blockquote>
<p>
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
</p>
<p>
If you depend on source files not generated by SWIG, before generated
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
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
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
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
move it to wherever it is convenient to call from your php script.
<p>
</p>
<p>
To test the extension from a PHP script, you need to load it first. You do
this by putting the line,
</p>
<blockquote><pre>
dl("/path/to/modulename.so"); // Load the module
</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>
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>
<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);
double bar(double, double b = 3.0);
...
</pre></blockquote>
Will be accessed in PHP like this :<p>
<p>
Will be accessed in PHP like this :
</p>
<blockquote><pre>
dl("default.so"); $a = foo(2);
$b = bar(3.5, -1.5);
@ -170,50 +205,65 @@ $c = bar(3.5); # Use default argument for 2nd parameter
</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
'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,
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
is handled for you, you can modify the variables in PHP as normal, e.g.
<p><p>
<blockquote><pre>%module example;
</p>
<blockquote><pre>
%module example;
...
double seki = 2;
...
int example_func(void);
</pre></blockquote>
is accessed as follow :<p>
<p>
is accessed as follow :
</p>
<blockquote><pre>
dl("example.so");
print $seki;
$seki = $seki * 2; # Does not affect C variable, still equal to 2
example_func(); # Syncs C variable to PHP Variable, now both 4
</pre></blockquote>
<p>
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
strings such as:<tt>_523d3f4_Circle_p</tt>, instead they are represented
as PHP resources, rather like MySQL connection handles.
</p>
<p>
You can also explicitly create a NULL pointer as a string "NULL"
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>
<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 {
public:
@ -224,7 +274,11 @@ public:
};
</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>
Vector_x_set($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
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
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,
(e.g. no dollar sign is needed to access them. ) For example, with a swig file like this,
<p>
</p>
<blockquote><pre>
%module example
#define PI 3.14159
%constant int E = 2.71828
</pre>
</blockquote>
<p>
you can access from in your php script like this,
</p>
<blockquote><pre>
dl("libexample.so");
@ -274,16 +332,19 @@ echo "E = " . E . "\n";
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
set to the constants name. For example,
<p>
</p>
<blockquote><pre>
%module example
#define EASY_TO_MISPELL 0
</pre>
</blockquote>
accessed incorrectly in PHP,
<p>
accessed incorrectly in PHP,
</p>
<blockquote>
<pre>
dl("libexample.so");
@ -296,93 +357,120 @@ if(EASY_TO_MISPEL) {
</pre>
</blockquote>
<p>
<p>
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,
rather than the value of the constant which would be false. This is a feature.
</p>
<p>
The second 'feature' is that although constants are case sensitive (by default),
you cannot declare a constant twice with alternative cases. E.g.,
<p>
</p>
<blockquote>
<pre>
%module example
#define TEST Hello
#define Test World
</pre>
</blockquote>
accessed from PHP,
<p>
<pre>
accessed from PHP,
</p>
<blockquote>
<pre>
dl("libexample.so");
echo TEST, Test;
</blockquote>
</pre>
</blockquote>
<p>
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
'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.
</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
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.
( 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
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.
</p>
<p>
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>
<p>
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
your .i file. No longer are the shadow classes defined in
the <tt>.php</tt> file, it will not contain significantly more support PHP
code.
</p>
<p>
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
functions like before.
</p>
<p>
.... ( 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
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
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
is currently worked around by doing the following,
</p>
<ul>
<li>Create the new PHP 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.
</ul>
<p>
This is rather convoluted and hopefully will be improved upon in a later
release.
<p><p>
</p>
<p>
Because the internal wrapped objects are wrapped in PHP resources, PHP
handles the cleaning up when there are no more references to the wrapped
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
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
@ -398,8 +486,11 @@ class Ko {
};
</pre></blockquote>
<p>
would be accessed in PHP as,
</p>
<blockquote><pre>
dl("libexample.so");
@ -416,7 +507,7 @@ echo "There has now been " . Ko::threats() . " threats\n";
</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,
@ -445,21 +536,28 @@ function is called.
%include "example.h"
</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
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
in each script.
</p>
<p>
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
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>
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
and includes the extra command line arguments from the module you have added.
</p>
<p>
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 (
@ -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.
In most cases <tt>Makefile.in</tt> will be complete, especially if you
make use of <tt>-withlibs</tt> and <tt>-withincs</tt>
</p>
<blockquote><pre>
swig -php4 -phpfull -withlibs "xapian omquery" --withincs "om.h"
</pre></blockquote>
<p>
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
search for om.h
</p>
<p>
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,
@ -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
the config.m4 file to ensure the correct libraries and header files are
installed.)
</p>
<p>
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
which contains your new module. You can test it with a php script which
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>

View file

@ -5,44 +5,48 @@
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>5 SWIG and Pike</H1>
<H1><a name="Pike"></a>24 SWIG and Pike</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Preliminaries</a>
<li><a href="#Pike_nn2">Preliminaries</a>
<ul>
<li><a href="#n3">Running SWIG</a>
<li><a href="#n4">Getting the right header files</a>
<li><a href="#n5">Using your module</a>
<li><a href="#Pike_nn3">Running SWIG</a>
<li><a href="#Pike_nn4">Getting the right header files</a>
<li><a href="#Pike_nn5">Using your module</a>
</ul>
<li><a href="#n6">Basic C/C++ Mapping</a>
<li><a href="#Pike_nn6">Basic C/C++ Mapping</a>
<ul>
<li><a href="#n7">Modules</a>
<li><a href="#n8">Functions</a>
<li><a href="#n9">Global variables</a>
<li><a href="#n10">Constants and enumerated types</a>
<li><a href="#n11">Constructors and Destructors</a>
<li><a href="#n12">Static Members</a>
<li><a href="#Pike_nn7">Modules</a>
<li><a href="#Pike_nn8">Functions</a>
<li><a href="#Pike_nn9">Global variables</a>
<li><a href="#Pike_nn10">Constants and enumerated types</a>
<li><a href="#Pike_nn11">Constructors and Destructors</a>
<li><a href="#Pike_nn12">Static Members</a>
</ul>
</ul>
<!-- INDEX -->
<p>
This chapter describes SWIG support for Pike. As of this writing, the
SWIG Pike module is still under development and is not considered
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
of Pike.<p>
of Pike.
</p>
<p>
This chapter covers most SWIG features, but certain low-level details
are covered in less depth than in earlier chapters. At the very
least, make sure you read the "<a
href="file:///home/jlj/src/SWIG/Doc/Manual/SWIG.html">SWIG Basics</a>"
least, make sure you read the "<a href="SWIG.html#SWIG">SWIG Basics</a>"
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:
@ -57,35 +61,46 @@ If you're building a C++ extension, be sure to add the <tt>-c++</tt> option:
<blockquote>
<pre>$ <b>swig -c++ -pike example.i</b><br></pre>
</blockquote>
<p>
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).
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
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
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
can use the <tt>-o</tt> option:
</p>
<blockquote>
<pre>$ <b>swig -pike -o pseudonym.c example.i</b><br></pre>
</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
path to the Pike header files. These files are usually contained in a
directory such as
<p> </p>
</p>
<blockquote>
<pre>/usr/local/pike/7.4.10/include/pike<br></pre>
</blockquote>
<p>
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.
You're looking for files with the names <tt>global.h</tt>, <tt>program.h</tt>
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:
@ -98,10 +113,10 @@ Pike v7.4 release 10 running Hilfe v3.5 (Incremental Pike Frontend)
(1) Result: 24
</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
@ -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
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
@ -131,7 +146,7 @@ exactly as you'd expect it to:
(1) Result: 24
</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
@ -156,19 +171,19 @@ will result in two functions, <tt>Foo_get()</tt> and <tt>Foo_set()</tt>:
(3) Result: 3.141590
</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,
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
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
@ -190,4 +205,4 @@ public:
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_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>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>0 Preface</H1>
<H1><a name="Preface"></a>1 Preface</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Introduction</a>
<li><a href="#n3">Special Introduction for Version 1.3</a>
<li><a href="#n4">SWIG Versions</a>
<li><a href="#n5">SWIG resources</a>
<li><a href="#n6">Prerequisites</a>
<li><a href="#n7">Organization of this manual</a>
<li><a href="#n8">How to avoid reading the manual</a>
<li><a href="#n9">Backwards Compatibility</a>
<li><a href="#n10">Credits</a>
<li><a href="#n11">Bug reports</a>
<li><a href="#Preface_nn2">Introduction</a>
<li><a href="#Preface_nn3">Special Introduction for Version 1.3</a>
<li><a href="#Preface_nn4">SWIG Versions</a>
<li><a href="#Preface_nn5">SWIG resources</a>
<li><a href="#Preface_nn6">Prerequisites</a>
<li><a href="#Preface_nn7">Organization of this manual</a>
<li><a href="#Preface_nn8">How to avoid reading the manual</a>
<li><a href="#Preface_nn9">Backwards Compatibility</a>
<li><a href="#Preface_nn10">Credits</a>
<li><a href="#Preface_nn11">Bug reports</a>
</ul>
<!-- 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
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
@ -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
is involved.
<p>
<a name="n3"></a><H2>0.2 Special Introduction for Version 1.3</H2>
<H2><a name="Preface_nn3"></a>1.2 Special Introduction for Version 1.3</H2>
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,
and Tcl.
<p>
<a name="n4"></a><H2>0.3 SWIG Versions</H2>
<H2><a name="Preface_nn4"></a>1.3 SWIG Versions</H2>
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
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>
<a href="http://www.swig.org">http://www.swig.org</a>
@ -85,27 +83,31 @@ implementation tricks.
<p>
You can also subscribe to the SWIG mailing list by visiting the page
</p>
<p>
<blockquote><pre><a href="http://mailman.cs.uchicago.edu/listinfo/swig">http://mailman.cs.uchicago.edu/listinfo/swig</a>
<blockquote><pre>
<a href="http://www.swig.org/mail.html">http://www.swig.org/mail.html</a>
</pre></blockquote>
<p>
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>
CVS access to the latest version of SWIG is also available. More information
about this can be obtained at:
</p>
<p>
<blockquote><pre><a href="http://www.swig.org/cvs.html">http://www.swig.org/cvs.html</a>
<blockquote><pre>
<a href="http://www.swig.org/cvs.html">http://www.swig.org/cvs.html</a>
</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
have at least heard of scripting languages such as
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
scripting language extensions is somewhat more complicated than
writing a normal C program.
</p>
<p>
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
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
@ -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
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
@ -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
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
@ -164,7 +167,7 @@ for the large number of new features that have been
added---namespaces, templates, smart pointers, overloaded methods,
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
@ -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
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
@ -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
can only fix bugs if we know about them.
<p><hr>
<hr>
<address>SWIG 1.3 - Last Modified : March 9, 2003</address>
</body>
</html>

View file

@ -5,17 +5,18 @@
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>6 Preprocessing</H1>
<H1><a name="Preprocessor"></a>7 Preprocessing</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">File inclusion</a>
<li><a href="#n3">File imports</a>
<li><a href="#n4">Conditional Compilation</a>
<li><a href="#n5">Macro Expansion</a>
<li><a href="#n6">SWIG Macros</a>
<li><a href="#n7">C99 and GNU Extensions</a>
<li><a href="#n8">Preprocessing and %{ ... %} blocks</a>
<li><a href="#n9">Preprocessing and { ... }</a>
<li><a href="#Preprocessor_nn2">File inclusion</a>
<li><a href="#Preprocessor_nn3">File imports</a>
<li><a href="#Preprocessor_nn4">Conditional Compilation</a>
<li><a href="#Preprocessor_nn5">Macro Expansion</a>
<li><a href="#Preprocessor_nn6">SWIG Macros</a>
<li><a href="#Preprocessor_nn7">C99 and GNU Extensions</a>
<li><a href="#Preprocessor_nn8">Preprocessing and %{ ... %} blocks</a>
<li><a href="#Preprocessor_nn9">Preprocessing and { ... }</a>
<li><a href="#Preprocessor_nn10">Viewing preprocessor output</a>
</ul>
<!-- 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
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
@ -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
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.
@ -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
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>,
<tt>#ifndef</tt>, <tt>#else</tt>, <tt>#endif</tt> to conditionally
include parts of an interface. The following symbols are predefined
by SWIG when it is parsing the interface:
</p>
<p>
<blockquote><pre>
SWIG Always defined when SWIG is processing a file
SWIGMAC Defined when running SWIG on the Macintosh
@ -116,13 +118,15 @@ __cplusplus Defined when -c++ option used
</pre>
</blockquote>
<p>
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
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
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
@ -140,6 +144,7 @@ you may get some extra constants such as <tt>_FOO_H</tt> showing up in the scrip
<p>
More complex macros can be defined in the standard way. For example:
</p>
<blockquote>
<pre>
@ -157,18 +162,19 @@ The following operators can appear in macro definitions:
<ul>
<li><tt>#x</tt><br>
Converts macro argument <tt>x</tt> to a string surrounded by double quotes ("x").
</li>
<p>
<li><tt>x ## y</tt><br>
Concatenates x and y together to form <tt>xy</tt>.
</li>
<p>
<li><tt>`x`</tt><br>
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.
</li>
</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.
@ -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,
many of SWIG's advanced features and libraries are built using this mechanism (such as C++ template
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:
@ -227,10 +234,11 @@ macros defined using <tt>%define</tt>.
<p>
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:
</p>
<blockquote>
<pre>
DEBUGF("hello"); --> fprintf(stderr,"hello",);
DEBUGF("hello"); --&gt; fprintf(stderr,"hello",);
</pre>
</blockquote>
@ -244,6 +252,7 @@ To get rid of the extra comma, use <tt>##</tt> like this:
<p>
SWIG also supports GNU-style variadic macros. For example:
</p>
<blockquote>
<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
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,
@ -276,7 +285,7 @@ int blah() {
the contents of the <tt>%{ ... %}</tt> block are copied without
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,
@ -310,17 +319,21 @@ to actually go into the wrapper file, prefix the preprocessor directives with <t
</pre>
</blockquote>
<p>
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>
<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.
When the <tt>-E</tt> switch is used, SWIG will not generate any wrappers.
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.
</p>
<p><hr>
<hr>
<address>SWIG 1.3 - Last Modified : March 9, 2003</address>
</body>

File diff suppressed because it is too large Load diff

View file

@ -4,77 +4,76 @@
<title>SWIG and Ruby</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a>
<a name="n1"></a><H1>23 SWIG and Ruby</H1>
<H1><a name="Ruby"></a>26 SWIG and Ruby</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Preliminaries</a>
<li><a href="#Ruby_nn2">Preliminaries</a>
<ul>
<li><a href="#n3">Running SWIG</a>
<li><a href="#n4">Getting the right header files</a>
<li><a href="#n5">Compiling a dynamic module</a>
<li><a href="#n6">Using your module</a>
<li><a href="#n7">Static linking</a>
<li><a href="#n8">Compilation of C++ extensions</a>
<li><a href="#Ruby_nn3">Running SWIG</a>
<li><a href="#Ruby_nn4">Getting the right header files</a>
<li><a href="#Ruby_nn5">Compiling a dynamic module</a>
<li><a href="#Ruby_nn6">Using your module</a>
<li><a href="#Ruby_nn7">Static linking</a>
<li><a href="#Ruby_nn8">Compilation of C++ extensions</a>
</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>
<li><a href="#n10">Running SWIG from Developer Studio</a>
<li><a href="#Ruby_nn10">Running SWIG from Developer Studio</a>
</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>
<li><a href="#n12">Modules</a>
<li><a href="#n13">Functions</a>
<li><a href="#n14">Variable Linking</a>
<li><a href="#n15">Constants</a>
<li><a href="#n16">Pointers</a>
<li><a href="#n17">Structures</a>
<li><a href="#n18">C++ classes</a>
<li><a href="#n19">C++ Inheritance</a>
<li><a href="#n20">C++ Overloaded Functions</a>
<li><a href="#n21">C++ Operators</a>
<li><a href="#n22">C++ namespaces</a>
<li><a href="#n23">C++ templates</a>
<li><a href="#n24">C++ Smart Pointers</a>
<li><a href="#n25">Cross-Language Polymorphism</a>
<li><a href="#Ruby_nn12">Modules</a>
<li><a href="#Ruby_nn13">Functions</a>
<li><a href="#Ruby_nn14">Variable Linking</a>
<li><a href="#Ruby_nn15">Constants</a>
<li><a href="#Ruby_nn16">Pointers</a>
<li><a href="#Ruby_nn17">Structures</a>
<li><a href="#Ruby_nn18">C++ classes</a>
<li><a href="#Ruby_nn19">C++ Inheritance</a>
<li><a href="#Ruby_nn20">C++ Overloaded Functions</a>
<li><a href="#Ruby_nn21">C++ Operators</a>
<li><a href="#Ruby_nn22">C++ namespaces</a>
<li><a href="#Ruby_nn23">C++ templates</a>
<li><a href="#ruby_cpp_smart_pointers">C++ Smart Pointers</a>
<li><a href="#Ruby_nn25">Cross-Language Polymorphism</a>
<ul>
<li><a href="#n26">Exception Unrolling</a>
<li><a href="#Ruby_nn26">Exception Unrolling</a>
</ul>
</ul>
<li><a href="#n27">Input and output parameters</a>
<li><a href="#n28">Simple exception handling </a>
<li><a href="#n29">Typemaps</a>
<li><a href="#Ruby_nn27">Input and output parameters</a>
<li><a href="#Ruby_nn28">Simple exception handling </a>
<li><a href="#Ruby_nn29">Typemaps</a>
<ul>
<li><a href="#n30">What is a typemap?</a>
<li><a href="#n31">Ruby typemaps</a>
<li><a href="#n32">Typemap variables</a>
<li><a href="#n33">Useful Functions</a>
<li><a href="#Ruby_nn30">What is a typemap?</a>
<li><a href="#Ruby_nn31">Ruby typemaps</a>
<li><a href="#Ruby_nn32">Typemap variables</a>
<li><a href="#Ruby_nn33">Useful Functions</a>
<ul>
<li><a href="#n34">C Datatypes to Ruby Objects</a>
<li><a href="#n35">Ruby Objects to C Datatypes</a>
<li><a href="#n36">Macros for VALUE</a>
<li><a href="#n37">Exceptions</a>
<li><a href="#n38">Iterators</a>
<li><a href="#Ruby_nn34">C Datatypes to Ruby Objects</a>
<li><a href="#Ruby_nn35">Ruby Objects to C Datatypes</a>
<li><a href="#Ruby_nn36">Macros for VALUE</a>
<li><a href="#Ruby_nn37">Exceptions</a>
<li><a href="#Ruby_nn38">Iterators</a>
</ul>
<li><a href="#n39">Typemap Examples</a>
<li><a href="#n40">Converting a Ruby array to a char **</a>
<li><a href="#n41">Collecting arguments in a hash</a>
<li><a href="#n42">Pointer handling</a>
<li><a href="#ruby_typemap_examples">Typemap Examples</a>
<li><a href="#Ruby_nn40">Converting a Ruby array to a char **</a>
<li><a href="#Ruby_nn41">Collecting arguments in a hash</a>
<li><a href="#Ruby_nn42">Pointer handling</a>
<ul>
<li><a href="#n43">Ruby Datatype Wrapping</a>
<li><a href="#Ruby_nn43">Ruby Datatype Wrapping</a>
</ul>
</ul>
<li><a href="#n44">Operator overloading</a>
<li><a href="#ruby_operator_overloading">Operator overloading</a>
<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>
<li><a href="#n46">Advanced Topics</a>
<li><a href="#Ruby_nn46">Advanced Topics</a>
<ul>
<li><a href="#n47">Creating Multi-Module Packages</a>
<li><a href="#n48">Defining Aliases</a>
<li><a href="#n49">Predicate Methods</a>
<li><a href="#n50">Specifying Mixin Modules</a>
<li><a href="#n51">Interacting with Ruby's Garbage Collector</a>
<li><a href="#Ruby_nn47">Creating Multi-Module Packages</a>
<li><a href="#Ruby_nn48">Defining Aliases</a>
<li><a href="#Ruby_nn49">Predicate Methods</a>
<li><a href="#Ruby_nn50">Specifying Mixin Modules</a>
<li><a href="#Ruby_nn51">Interacting with Ruby's Garbage Collector</a>
</ul>
</ul>
<!-- INDEX -->
@ -83,7 +82,7 @@
<p>This chapter describes SWIG's support of Ruby. </p>
<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
@ -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
found in
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
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>
To build a Ruby module, run SWIG using the <tt>-ruby</tt> option:</p>
<p></p>
<p></p>
<blockquote>
<pre>$ <b>swig -ruby example.i</b>
</pre>
</blockquote>
If building a C++ extension, add the <tt>-c++</tt> option:
<p></p>
<blockquote>
<pre>$ <b>swig -c++ -ruby example.i</b>
</pre>
@ -125,13 +123,16 @@ build a
Ruby extension module. To finish building the module, you need to
compile this
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>
header file. This file is usually contained in a directory such as
<p></p>
</p>
<blockquote>
<pre>/usr/local/lib/ruby/1.6/i686-linux/ruby.h<br></pre>
</blockquote>
@ -149,8 +150,7 @@ can run Ruby to find out. For example:
</pre>
</blockquote>
<a name="n5"></a>
<a name="n5"></a><H3>23.1.3 Compiling a dynamic module</H3>
<H3><a name="Ruby_nn5"></a>26.1.3 Compiling a dynamic module</H3>
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
steps
described in the <tt>README.EXT</tt> file from the Ruby distribution:
<p></p>
<ol>
<li>Create a file called <tt>extconf.rb</tt> that looks like the
following:
@ -169,7 +169,6 @@ following:
</blockquote>
</li>
<li>Type the following to build the extension:
<p></p>
<blockquote>
<pre>$ <b>ruby extconf.rb</b>
$ <b>make</b>
@ -194,7 +193,7 @@ platform.
For example, a typical sequence of commands for the Linux operating
system
would look something like this:
<p></p>
<blockquote>
<pre>$ <b>swig -ruby example.i</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">
SWIG Wiki</a> for additional information.
<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>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:
<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
<b>lowercase</b> module name with SWIG's <tt>%module</tt> directive.
SWIG will automatically correct the resulting Ruby module name for your
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
Ruby module name "Example".
<a name="n7"></a>
<a name="n7"></a><H3>23.1.5 Static linking</H3>
<H3><a name="Ruby_nn7"></a>26.1.5 Static linking</H3>
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.
</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>
On most machines, C++ extension modules should be linked using the C++
compiler. For example:
</p>
<p></p>
<blockquote>
<pre>$ <b>swig -c++ -ruby example.i</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>
</blockquote>
<hr>
<a name="n9"></a>
<a name="n9"></a><H2>23.2 Building Ruby Extensions under Windows 95/NT</H2>
<H2><a name="Ruby_nn9"></a>26.2 Building Ruby Extensions under Windows 95/NT</H2>
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
will need the Ruby header files.
<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
@ -314,8 +311,7 @@ studio, SWIG
can be invoked as a custom build option. The process roughly follows
these
steps :
<p></p>
<p></p>
<ul>
<li>Open up a new workspace and use the AppWizard to select a DLL
project.
@ -381,8 +377,7 @@ run
your new Ruby extension, simply run Ruby and use the <tt>require</tt>
command
as normal. For example if you have this ruby file run.rb:</p>
<p></p>
<p></p>
<blockquote>
<pre># file: run.rb<br>require 'Example'<br><br># Call a c function<br>print "Foo = ", Example.Foo, "\n"<br></pre>
</blockquote>
@ -394,17 +389,15 @@ Ruby script from the DOS/Command prompt:
Foo = 3.0
</pre>
</blockquote>
<p>
</p>
<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++
declarations
in your SWIG interface files to Ruby constructs.
<a name="n12"></a>
<a name="n12"></a><H3>23.3.1 Modules</H3>
<H3><a name="Ruby_nn12"></a>26.3.1 Modules</H3>
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
conflict
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
the SWIG interface file <tt>example.i</tt>:
<p></p>
<blockquote>
<pre>%module example<br><br>int fact(int n);<br></pre>
</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
that
can be used like so:
<p></p>
<blockquote>
<pre>$ <b>irb</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
</pre>
</blockquote>
<a name="n14"></a>
<a name="n14"></a><H3>23.3.3 Variable Linking</H3>
<H3><a name="Ruby_nn14"></a>26.3.3 Variable Linking</H3>
C/C++ global variables are wrapped as a pair of singleton methods for
@ -504,8 +496,7 @@ variables:
</blockquote>
<p>
Now look at the Ruby interface:</p>
<p></p>
<p></p>
<blockquote>
<pre>$ <b>irb</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
explicitly
disabled using <tt>%mutable</tt>.
<a name="n15"></a>
<a name="n15"></a><H3>23.3.4 Constants</H3>
<H3><a name="Ruby_nn15"></a>26.3.4 Constants</H3>
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>
Remember to use the :: operator in Ruby to get at these constant
values, e.g.
<p></p>
<blockquote>
<pre>$ <b>irb</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
</pre>
</blockquote>
<a name="n16"></a>
<a name="n16"></a><H3>23.3.5 Pointers</H3>
<H3><a name="Ruby_nn16"></a>26.3.5 Pointers</H3>
"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
example, consider a SWIG interface file containing only the
declarations:
<p></p>
<blockquote>
<pre>Foo *get_foo();<br>void set_foo(Foo *foo);<br></pre>
</blockquote>
@ -587,15 +576,14 @@ internally generated Ruby class:
</blockquote>
A <tt>NULL</tt> pointer is always represented by the Ruby <tt>nil</tt>
object.
<a name="n17"></a>
<a name="n17"></a><H3>23.3.6 Structures</H3>
<H3><a name="Ruby_nn17"></a>26.3.6 Structures</H3>
C/C++ structs are wrapped as Ruby classes, with accessor methods (i.e.
"getters"
and "setters") for all of the struct members. For example, this struct
declaration:
<p></p>
<blockquote>
<pre>struct Vector {<br> double x, y;<br>};<br></pre>
</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
access
structure data from Ruby as follows:
<p></p>
<blockquote>
<pre>$ <b>irb</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
C++
classes.</p>
<p></p>
<p><tt>const</tt> members of a structure are read-only. Data members
can also be
forced to be read-only using the <tt>%immutable</tt> directive (in
@ -654,7 +642,7 @@ produces a single accessor function like this:
</blockquote>
If you want to set an array member, you will need to supply a
"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
case, SWIG does generate code to set array members of type <tt>char</tt>
(allowing you to store a Ruby string in the structure).
@ -668,8 +656,7 @@ generates accessor functions such as this:
<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>
</blockquote>
<a name="n18"></a>
<a name="n18"></a><H3>23.3.7 C++ classes</H3>
<H3><a name="Ruby_nn18"></a>26.3.7 C++ classes</H3>
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
methods. So,
given the C++ class declaration:
<p></p>
<p></p>
<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>
</blockquote>
@ -705,8 +692,7 @@ In Ruby, these functions are used as follows:
<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>
</blockquote>
<a name="n19"></a>
<a name="n19"></a><H3>23.3.8 C++ Inheritance</H3>
<H3><a name="Ruby_nn19"></a>26.3.8 C++ Inheritance</H3>
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>
(i.e. they exhibit <a href="http://c2.com/cgi/wiki?DuckTyping">"Duck
Typing"</a>).
<a name="n20"></a>
<a name="n20"></a><H3>23.3.9 C++ Overloaded Functions</H3>
<H3><a name="Ruby_nn20"></a>26.3.9 C++ Overloaded Functions</H3>
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
arises--in this case, the
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>
<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
@ -909,9 +894,8 @@ Now, in Ruby, you can do this:
</blockquote>
More details about wrapping C++ operators into Ruby operators is
discussed in
the <a href="#n39">section on operator overloading</a>.
<a name="n22"></a>
<a name="n22"></a><H3>23.3.11 C++ namespaces</H3>
the <a href="#ruby_operator_overloading">section on operator overloading</a>.
<H3><a name="Ruby_nn22"></a>26.3.11 C++ namespaces</H3>
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
utilizes thousands of small deeply nested namespaces each with
identical symbol names, well, then you get what you deserve.
<a name="n23"></a>
<a name="n23"></a><H3>23.3.12 C++ templates</H3>
<H3><a name="Ruby_nn23"></a>26.3.12 C++ templates</H3>
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>
Obviously, there is a lot more to template wrapping than shown in these
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.
<a name="n24"></a>
<a name="n24"></a><H3>23.3.13 C++ Smart Pointers</H3>
<H3><a name="ruby_cpp_smart_pointers"></a>26.3.13 C++ Smart Pointers</H3>
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>
<pre>irb(main):004:0&gt; <b>f = p.__deref__()</b> # Returns underlying Foo *<br></pre>
</blockquote>
<a name="n25"></a>
<a name="n25"></a><H3>23.3.14 Cross-Language Polymorphism</H3>
<H3><a name="Ruby_nn25"></a>26.3.14 Cross-Language Polymorphism</H3>
SWIG's Ruby module supports cross-language polymorphism (a.k.a. the
"directors"
feature) similar to that for SWIG's Python module. Rather than
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
secton just notes the differences that you need to be aware of when
using this
feature with Ruby.
<a name="n26"></a>
<a name="n26"></a><H4>23.3.14.1 Exception Unrolling</H4>
<H4><a name="Ruby_nn26"></a>26.3.14.1 Exception Unrolling</H4>
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
place.
<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
@ -1154,18 +1134,17 @@ In Ruby:
<pre>r, c = Example.get_dimensions(m)<br></pre>
</blockquote>
<hr>
<a name="n28"></a>
<a name="n28"></a><H2>23.5 Simple exception handling </H2>
<H2><a name="Ruby_nn28"></a>26.5 Simple exception handling </H2>
The SWIG <tt>%exception</tt> directive can be used to define a
user-definable
exception handler that can convert C/C++ errors into Ruby exceptions.
The
chapter on <a href="Customization.html">Customization Features</a>
chapter on <a href="Customization.html#Customization">Customization Features</a>
contains more
details, but suppose you have a C++ class like the following :
<p></p>
<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>
</blockquote>
@ -1174,7 +1153,7 @@ out-of-bounds
access, you might want to catch this in the Ruby extension by writing
the
following in an interface file:
<p></p>
<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>
</blockquote>
@ -1196,7 +1175,7 @@ functions
named <tt>getitem</tt> and <tt>setitem</tt>.
<p>Since SWIG's exception handling is user-definable, you are not
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.
</p>
<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>.
</p>
<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
@ -1219,22 +1198,22 @@ for various C/C++ datatypes using the <tt>%typemap</tt> directive.
This
is an advanced topic that assumes familiarity with the Ruby C API as
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
required part of using SWIG---the default wrapping behavior is enough
in most cases.
Typemaps are only used if you want to change some aspect of the
primitive
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
to a specific C datatype. For example, to convert integers from Ruby to
C,
you might define a typemap like this:
<p></p>
<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>
</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
sample code:
</p>
<p></p>
<blockquote>
<pre>require 'example'<br><br>puts Example.fact(6)<br></pre>
</blockquote>
@ -1308,8 +1287,7 @@ follows (notice how the length parameter is omitted):
<blockquote>
<pre>puts Example.count('o','Hello World')<br>2<br></pre>
</blockquote>
<a name="n31"></a>
<a name="n31"></a><H3>23.6.2 Ruby typemaps</H3>
<H3><a name="Ruby_nn31"></a>26.6.2 Ruby typemaps</H3>
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
occur.
</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
examples</a>
<a name="n32"></a>
<a name="n32"></a><H3>23.6.3 Typemap variables</H3>
<H3><a name="Ruby_nn32"></a>26.6.3 Typemap variables</H3>
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
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
variables:
<p><tt>$1</tt>
@ -1410,8 +1387,7 @@ so that their values can be properly assigned.
<tt>$symname</tt>
<blockquote>The Ruby name of the wrapper function being created.
</blockquote>
<a name="n33"></a>
<a name="n33"></a><H3>23.6.4 Useful Functions</H3>
<H3><a name="Ruby_nn33"></a>26.6.4 Useful Functions</H3>
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
and Andrew Hunt.)
<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>
<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>
<a name="n35"></a>
<a name="n35"></a><H4>23.6.4.2 Ruby Objects to C Datatypes</H4>
<H4><a name="Ruby_nn35"></a>26.6.4.2 Ruby Objects to C Datatypes</H4>
<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>
</blockquote>
<a name="n36"></a>
<a name="n36"></a><H4>23.6.4.3 Macros for VALUE</H4>
<H4><a name="Ruby_nn36"></a>26.6.4.3 Macros for VALUE</H4>
<p>
@ -1451,8 +1425,7 @@ and Andrew Hunt.)
<blockquote>capacity of the Ruby array</blockquote>
<tt>RARRAY(arr)-&gt;ptr</tt>
<blockquote>pointer to array storage</blockquote>
<a name="n37"></a>
<a name="n37"></a><H4>23.6.4.4 Exceptions</H4>
<H4><a name="Ruby_nn37"></a>26.6.4.4 Exceptions</H4>
<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
<i>fmt</i> and remaining arguments are interpreted as with <tt>printf()</tt>.
</blockquote>
<a name="n38"></a>
<a name="n38"></a><H4>23.6.4.5 Iterators</H4>
<H4><a name="Ruby_nn38"></a>26.6.4.5 Iterators</H4>
<p>
@ -1544,15 +1516,13 @@ value)</tt>
<tt>void rb_throw(const char *tag, VALUE value)</tt>
<blockquote> Equivalent to Ruby's <tt>throw</tt>.
</blockquote>
<a name="n39"></a>
<a name="n39"></a><H3>23.6.5 Typemap Examples</H3>
<H3><a name="ruby_typemap_examples"></a>26.6.5 Typemap Examples</H3>
This section includes a few examples of typemaps. For more examples,
you
might look at the examples in the <tt>Example/ruby</tt> directory.
<a name="n40"></a>
<a name="n40"></a><H3>23.6.6 Converting a Ruby array to a char **</H3>
<H3><a name="Ruby_nn40"></a>26.6.6 Converting a Ruby array to a char **</H3>
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
strings. The following SWIG interface file allows a Ruby Array instance
to be used as a <tt>char **</tt> object.
<p></p>
<p></p>
<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>
</blockquote>
When this module is compiled, the wrapped C function now operates as
follows :
<p></p>
<p></p>
<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>
</blockquote>
@ -1580,7 +1550,7 @@ allocation is used to allocate memory for the array, the "freearg"
typemap is
used to later release this memory after the execution of the C
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
@ -1736,8 +1706,7 @@ uses
the extension, can be found in the <tt>Examples/ruby/hashargs</tt>
directory
of the SWIG distribution.
<a name="n42"></a>
<a name="n42"></a><H3>23.6.8 Pointer handling</H3>
<H3><a name="Ruby_nn42"></a>26.6.8 Pointer handling</H3>
Occasionally, it might be necessary to convert pointer values that have
@ -1797,8 +1766,7 @@ typemap variable <tt>$1_descriptor</tt>. For example:
<blockquote>
<pre>%typemap(in) Foo * {<br> SWIG_ConvertPtr($input, (void **) &amp;$1, $1_descriptor, 1);<br>}<br></pre>
</blockquote>
<a name="n43"></a>
<a name="n43"></a><H4>23.6.8.1 Ruby Datatype Wrapping</H4>
<H4><a name="Ruby_nn43"></a>26.6.8.1 Ruby Datatype Wrapping</H4>
<p>
@ -1822,8 +1790,7 @@ from the data object
<i>obj</i> and assigns that pointer to <i>ptr</i>.
</blockquote>
<hr>
<a name="n44"></a>
<a name="n44"></a><H2>23.7 Operator overloading</H2>
<H2><a name="ruby_operator_overloading"></a>26.7 Operator overloading</H2>
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
handling <i>inequality</i> since Ruby parses the expression <i>a != b</i>
as <i>!(a == b)</i>.
<a name="n45"></a>
<a name="n45"></a><H3>23.7.1 Example: STL Vector to Ruby Array</H3>
<H3><a name="Ruby_nn45"></a>26.7.1 Example: STL Vector to Ruby Array</H3>
<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
similar typemaps for other STL structures:
</p>
<p></p>
<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>
</blockquote>
@ -1864,19 +1830,20 @@ preprocessor step
to determine the actual object from the class name.
<p>To use the macro with a class Foo, the following is used:
</p>
<p></p>
<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>
It is also possible to create a STL vector of Ruby objects:
<p></p>
<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>
</blockquote>
It is also possible to create a Ruby array from a vector of static data
types:
<p></p>
<pre><blockquote>
<blockquote><pre>
%define VECTOR_TO_RUBY_ARRAY(vectorclassname, classname)
%typemap(ruby, out) vectorclassname &amp;, const vectorclassname &amp; {
VALUE arr = rb_ary_new2($1-&gt;size());
@ -1893,16 +1860,14 @@ types:
$result = arr;
}
%enddef
</blockquote></pre>
<a name="n46"></a>
<a name="n46"></a><H2>23.8 Advanced Topics</H2>
</pre></blockquote>
<H2><a name="Ruby_nn46"></a>26.8 Advanced Topics</H2>
<a name="n47"></a>
<a name="n47"></a><H3>23.8.1 Creating Multi-Module Packages</H3>
<H3><a name="Ruby_nn47"></a>26.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
of creating multi-module extensions with SWIG, and in particular
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
by building
the <b>Shape</b> extension module:
<p></p>
<blockquote>
<pre>$ <b>swig -c++ -ruby -c shape.i</b>
</pre>
@ -1933,14 +1898,14 @@ SWIG generates a wrapper file named <tt>shape_wrap.cxx</tt>. To
compile this
into a dynamically loadable extension for Ruby, prepare an <tt>extconf.rb</tt>
script using this template:
<p></p>
<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>
</blockquote>
Run this script to create a <tt>Makefile</tt> and then type <tt>make</tt>
to
build the shared library:
<p></p>
<blockquote>
<pre>$ <b>ruby extconf.rb</b>
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
interactively in IRB to confirm that the <tt>Shape</tt> and <tt>Circle</tt>
modules are properly loaded and initialized:
<p></p>
<blockquote>
<pre>$ <b>irb</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
</pre>
</blockquote>
<a name="n48"></a>
<a name="n48"></a><H3>23.8.2 Defining Aliases</H3>
<H3><a name="Ruby_nn48"></a>26.8.2 Defining Aliases</H3>
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
<tt>%extend</tt> directive to add a new method of the aliased name
that calls the original function. For example:
<p></p>
<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>
</blockquote>
A better solution is to instead use the <tt>%alias</tt> directive
(unique to
SWIG's Ruby module). The previous example could then be rewritten as:
<p></p>
<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>
</blockquote>
@ -2032,11 +1996,11 @@ wrapper code that's usually associated with added methods like our
"features"
mechanism and so the same name matching rules used for other kinds of
features
apply (see the chapter on <a href="Customization.html">"Customization
apply (see the chapter on <a href="Customization.html#Customization">"Customization
Features"</a>)
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>
@ -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
methods.
For the previous example, this would look like:
<p></p>
<blockquote>
<pre>%predicate is_it_safe();<br><br>int is_it_safe();<br></pre>
</blockquote>
@ -2082,10 +2046,9 @@ Note that the <tt>%predicate</tt> directive is implemented using
SWIG's
"features" mechanism and so the same name matching rules used for other
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).
<a name="n50"></a>
<a name="n50"></a><H3>23.8.4 Specifying Mixin Modules</H3>
<H3><a name="Ruby_nn50"></a>26.8.4 Specifying Mixin Modules</H3>
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>
instance
method, e.g.
<p></p>
<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>
</blockquote>
then you can mix-in Ruby's <tt>Enumerable</tt> module to easily add a
lot
of functionality to your class:
<p></p>
<blockquote>
<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
"features" mechanism and so the same name matching rules used for other
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).
<a name="n51"></a>
<a name="n51"></a><H3>23.8.5 Interacting with Ruby's Garbage Collector</H3>
<H3><a name="Ruby_nn51"></a>26.8.5 Interacting with Ruby's Garbage Collector</H3>
<b>This section is still unfinished!</b>
@ -2163,8 +2125,8 @@ models
a zoo and the animals in the zoo:
</p>
<blockquote>
<pre>%module zoo<br><br>%{<br>#include <string>
#include <vector>
<pre>%module zoo<br><br>%{<br>#include &lt;string&gt;
#include &lt;vector&gt;
#include "zoo.h"
%}
@ -2185,8 +2147,7 @@ public:
class Zoo
{
protected:
std::vector<animal
*=""> 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>
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>
</blockquote>
Basically, a <tt>Zoo</tt> is modeled as a "container" for animals. And
we can
@ -2247,8 +2208,8 @@ of the
Ruby instances associated with those C++ <tt>Animal</tt> objects:
</p>
<blockquote>
<pre>void Zoo_markfunc(void *ptr)<br>{<br> Animal *cppAnimal;<br> VALUE rubyAnimal;<br> Zoo *zoo;<br> <br> zoo = static_cast<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>
<pre>void Zoo_markfunc(void *ptr)<br>{<br> Animal *cppAnimal;<br> VALUE rubyAnimal;<br> Zoo *zoo;<br> <br> zoo = static_cast&lt;zoo
*=""&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>
<em>SWIG_RubyInstanceFor() is an imaginary function that takes a
pointer
@ -2269,7 +2230,7 @@ are
implemented using SWIG's' "features" mechanism and so the same name
matching
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).
<hr>
<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>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>3 Scripting Languages</H1>
<H1><a name="Scripting"></a>4 Scripting Languages</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">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_nn2">The two language view of the world</a>
<li><a href="#Scripting_nn3">How does a scripting language talk to C?</a>
<ul>
<li><a href="#n4">Wrapper functions</a>
<li><a href="#n5">Variable linking</a>
<li><a href="#n6">Constants</a>
<li><a href="#n7">Structures and classes</a>
<li><a href="#n8">Shadow classes</a>
<li><a href="#Scripting_nn4">Wrapper functions</a>
<li><a href="#Scripting_nn5">Variable linking</a>
<li><a href="#Scripting_nn6">Constants</a>
<li><a href="#Scripting_nn7">Structures and classes</a>
<li><a href="#Scripting_nn8">Shadow classes</a>
</ul>
<li><a href="#n9">Building scripting language extensions</a>
<li><a href="#Scripting_nn9">Building scripting language extensions</a>
<ul>
<li><a href="#n10">Shared libraries and dynamic loading</a>
<li><a href="#n11">Linking with shared libraries</a>
<li><a href="#n12">Static linking</a>
<li><a href="#Scripting_nn10">Shared libraries and dynamic loading</a>
<li><a href="#Scripting_nn11">Linking with shared libraries</a>
<li><a href="#Scripting_nn12">Static linking</a>
</ul>
</ul>
<!-- INDEX -->
@ -32,16 +32,17 @@ This chapter provides a brief overview of scripting language extension
programming and the mechanisms by which scripting language interpreters
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
resulting system tends to look as follows:
</p>
<p><center><img src="ch2.1.png"></center><p>
<p>
<p>
<center><img src="ch2.1.png" alt="Scripting language input - C/C++ functions output"></center>
<p>
In this programming model, the scripting language interpreter is used
for high level control whereas the underlying functionality of the
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
scripts. However, most of the underlying functionality is written in
a low-level language like C or Fortran.
</p>
<p>
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
languages can be used for rapid prototyping, interactive debugging,
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
@ -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
function, arguments, and so forth. The next few sections illustrate
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>
<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;
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
necessary to write a special "wrapper" function that serves as the
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>
<li>Gather function arguments and make sure they are valid.
<li>Call the C function.
<li>Convert the return value into a form recognized by the scripting language.
</ul>
<p>
<p>
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>
int wrap_fact(ClientData clientData, Tcl_Interp *interp,
@ -129,14 +132,15 @@ int wrap_fact(ClientData clientData, Tcl_Interp *interp,
</pre></blockquote>
<p>
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
initialization function called by the language when the module is
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>int Wrap_Init(Tcl_Interp *interp) {
<blockquote><pre>
int Wrap_Init(Tcl_Interp *interp) {
Tcl_CreateCommand(interp, "fact", wrap_fact, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
return TCL_OK;
@ -145,41 +149,42 @@ requires code like the following :<p>
<p>
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>
Although the process of adding a new function to Tcl has been
illustrated, the procedure is almost identical for Perl and
Python. Both require special wrappers to be written and both need
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
C/C++ global variable to a variable in the scripting
language interpeter. For example, suppose you had the following
variable:<p>
<p>
variable:</p>
<blockquote><pre>double Foo = 3.5;
<blockquote><pre>
double Foo = 3.5;
</pre></blockquote>
<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>$a = $Foo * 2.3; # Evaluation
<blockquote><pre>
$a = $Foo * 2.3; # Evaluation
$Foo = $a + 2.0; # Assignment
</pre></blockquote>
<p>
To provide such access, variables are commonly manipulated using a
pair of get/set functions. For example, whenever the value of a
variable is read, a "get" function is invoked. Similarly, whenever
the value of a variable is changed, a "set" function is called.
</p>
<p>
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,
typing <tt>$Foo = 4</tt> would call the underlying set function to change
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
constants. For example:
<blockquote><pre>#define RED 0xff0000
<blockquote><pre>
#define RED 0xff0000
#define BLUE 0x0000ff
#define GREEN 0x00ff00
</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
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
@ -220,19 +227,20 @@ does C++ inheritance mean in a Perl interface?
The most straightforward technique for handling structures is to
implement a collection of accessor functions that hide the underlying
representation of a structure. For example,
</p>
<p>
<blockquote><pre>struct Vector {
<blockquote><pre>
struct Vector {
Vector();
~Vector();
double x,y,z;
};
</pre></blockquote>
can be transformed into the following set of functions :<p>
can be transformed into the following set of functions :
<p>
<blockquote><pre>Vector *new_Vector();
<blockquote><pre>
Vector *new_Vector();
void delete_Vector(Vector *v);
double Vector_x_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:
<p>
<blockquote><pre>% set v [new_Vector]
<blockquote><pre>
% set v [new_Vector]
% Vector_x_set $v 3.5
% Vector_y_get $v
% delete_Vector $v
% ...
</pre></blockquote>
<p>
<p>
Since accessor functions provide a mechanism for accessing the
internals of an object, the interpreter does not need to know anything
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
to create something known as a "shadow" class.
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
that looks like the original structure (that is, it "shadows" the real
C++ class). For example, if you
have the following C definition :<p>
have the following C definition :</p>
<blockquote><pre>
class Vector {
@ -277,13 +287,14 @@ public:
double x,y,z;
};
</pre></blockquote>
<p>
<p>
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:
</p>
<p>
<blockquote><pre>&gt;&gt;&gt; v = Vector()
<blockquote><pre>
&gt;&gt;&gt; v = Vector()
&gt;&gt;&gt; v.x = 3
&gt;&gt;&gt; v.y = 4
&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>
<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>
$v = new Vector;
@ -302,7 +313,7 @@ $v-&gt;{z} = -13;
</pre></blockquote>
Finally, in Tcl :<p>
Finally, in Tcl :
<blockquote><pre>
Vector v
@ -310,14 +321,17 @@ v configure -x 3 -y 4 -z 13
</pre></blockquote>
<p>
When shadow classes are used, two objects are at really work--one in
the scripting language, and an underlying C/C++ object. Operations
affect both objects equally and for all practical purposes, it appears
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++
application is adding your extensions to the scripting language
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
recompile the scripting language interpreter with your extensions
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>
<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
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>
<p>
To use your shared library, you simply use the corresponding command
in the scripting language (load, import, use, etc...). This will
import your module and allow you to start using it. For example:
</p>
<p>
<blockquote><pre>% load ./example.so
<blockquote><pre>
% load ./example.so
% fact 4
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
additional code in order to operate correctly. On many machines, you
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>c++ -shared example.o example_wrap.o -o example.so
<blockquote><pre>
c++ -shared example.o example_wrap.o -o example.so
</pre></blockquote>
<H3><a name="Scripting_nn11"></a>4.3.2 Linking with shared libraries</H3>
<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
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
these libraries at run-time. Otherwise, you may get an error such as
the following :<p>
the following :</p>
<p>
<blockquote><pre>&gt;&gt;&gt; import graph
<blockquote><pre>
&gt;&gt;&gt; import graph
Traceback (innermost last):
File "&lt;stdin&gt;", line 1, 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
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
approaches you can take.<p>
<p>
approaches you can take.</p>
<ul>
<li>Link your extension and explicitly tell the linker where the
required libraries are located. Often times, this can be done with a
@ -417,23 +435,25 @@ the path using linker options instead.
</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 extensions. The process usually involves compiling a short main
program that adds your customized commands to the language and starts
the interpreter. You then link your program with a library to produce
a new scripting language executable.
</p>
<p>
Although static linking is supported on all platforms, this is not
the preferred technique for building scripting language
extensions. In fact, there are very few practical reasons for doing this--consider
using shared libraries instead.
</p>
<p><hr>
<hr>
<address>SWIG 1.3 - Last Modified : July 16, 2001</address>
</body>
</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>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>11 Variable Length Arguments</H1>
<H1><a name="Varargs"></a>13 Variable Length Arguments</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Introduction</a>
<li><a href="#n3">The Problem</a>
<li><a href="#n4">Default varargs support</a>
<li><a href="#n5">Argument replacement using %varargs</a>
<li><a href="#n6">Varargs and typemaps</a>
<li><a href="#n7">Varargs wrapping with libffi</a>
<li><a href="#n8">Wrapping of va_list</a>
<li><a href="#n9">C++ Issues</a>
<li><a href="#n10">Discussion</a>
<li><a href="#Varargs_nn2">Introduction</a>
<li><a href="#Varargs_nn3">The Problem</a>
<li><a href="#Varargs_nn4">Default varargs support</a>
<li><a href="#Varargs_nn5">Argument replacement using %varargs</a>
<li><a href="#Varargs_nn6">Varargs and typemaps</a>
<li><a href="#Varargs_nn7">Varargs wrapping with libffi</a>
<li><a href="#Varargs_nn8">Wrapping of va_list</a>
<li><a href="#Varargs_nn9">C++ Issues</a>
<li><a href="#Varargs_nn10">Discussion</a>
</ul>
<!-- INDEX -->
@ -25,18 +25,19 @@
<b>(a.k.a, "The horror. The horror.")</b>
<p>
This chapter describes the problem of wrapping functions that take a
variable number of arguments. For instance, generating wrappers for
the C <tt>printf()</tt> family of functions.
</p>
<p>
This topic is sufficiently advanced to merit its own chapter. In
fact, support for varargs is an often requested feature that was first
added in SWIG-1.3.12. Most other wrapper generation tools have
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
@ -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
NULL-terminated list of pointers. A good example of this would
be a function like this:
</p>
<blockquote>
<pre>
@ -122,7 +124,7 @@ List make_list(const char *s, ...) {
</pre>
</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
@ -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
variable length arguments to another varargs function. It just
doesn't work.
</p>
<p>
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:
</p>
<blockquote>
<pre>
@ -159,6 +163,7 @@ frame followed by a call to <tt>printf()</tt>.
<p>
In contrast, suppose you attempted to make some kind of wrapper around
<tt>printf()</tt> using code like this:
</p>
<blockquote>
<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
compiler generate code for a function call involving an unknown number
of arguments of unknown types.
</p>
<p>
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
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.
</p>
<p>
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
can also support real varargs wrapping (with stack-frame manipulation) if you
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
@ -239,14 +247,14 @@ instance, you could make function calls like this (in Python):
<blockquote>
<pre>
>>> traceprintf("Hello World")
>>> traceprintf("Hello %s. Your number is %d\n" % (name, num))
&gt;&gt;&gt; traceprintf("Hello World")
&gt;&gt;&gt; traceprintf("Hello %s. Your number is %d\n" % (name, num))
</pre>
</blockquote>
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
@ -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.
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.
</p>
<p>
Argument replacement is not as useful when working with functions that accept
mixed argument types such as <tt>printf()</tt>. Providing general purpose
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:
@ -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.
<p>
To illustrate, here is a safer version of wrapping <tt>printf()</tt> in Python:
</p>
<blockquote>
<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
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.
</p>
<p>
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
instead of using <tt>%varargs</tt>, you might first write a typemap
like this:
</p>
<blockquote>
<pre>
@ -388,7 +401,7 @@ like this:
int argc;
for (i = 0; i &lt; 10; i++) args[i] = 0;
argc = PyTuple_Size(varargs);
if (argc > 10) {
if (argc &gt; 10) {
PyErr_SetString(PyExc_ValueError,"Too many arguments");
return NULL;
}
@ -427,15 +440,16 @@ this:
int execlp(const char *path, const char *arg, ...);
</pre>
</blockquote>
<p>
<p>
This patches everything up and creates a function that more or less
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
really want to elevate your guru status and increase your job
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
@ -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,
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
(<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
manner. Details about the library can be found in the libffi
distribution and are not repeated here.
</p>
<p>
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
arguments. To do this, you might make a few adjustments to the previous
example. For example:
</p>
<blockquote>
<pre>
@ -501,21 +517,21 @@ example. For example:
args = (char **) arg3;
/* Set up path parameter */
types[0] = &ffi_type_pointer;
values[0] = &arg1;
types[0] = &amp;ffi_type_pointer;
values[0] = &amp;arg1;
/* Set up first argument */
types[1] = &ffi_type_pointer;
values[1] = &arg2;
types[1] = &amp;ffi_type_pointer;
values[1] = &amp;arg2;
/* Set up rest of parameters */
for (i = 0; i &lt;= vc; i++) {
types[2+i] = &ffi_type_pointer;
values[2+i] = &args[i];
types[2+i] = &amp;ffi_type_pointer;
values[2+i] = &amp;args[i];
}
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3,
&ffi_type_uint, types) == FFI_OK) {
ffi_call(&cif, (void (*)()) execlp, &result, values);
if (ffi_prep_cif(&amp;cif, FFI_DEFAULT_ABI, vc+3,
&amp;ffi_type_uint, types) == FFI_OK) {
ffi_call(&amp;cif, (void (*)()) execlp, &amp;result, values);
} else {
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
free(types);
@ -541,6 +557,7 @@ first place?!?" Obviously, those are questions you'll have to answer for yourse
<p>
As a more extreme example of libffi, here is some code that attempts to wrap <tt>printf()</tt>,
</p>
<blockquote>
<pre>
@ -604,32 +621,32 @@ As a more extreme example of libffi, here is some code that attempts to wrap <tt
args = (vtype *) arg2;
/* Set up fmt parameter */
types[0] = &ffi_type_pointer;
values[0] = &arg1;
types[0] = &amp;ffi_type_pointer;
values[0] = &amp;arg1;
/* Set up rest of parameters */
for (i = 0; i &lt; vc; i++) {
switch(args[i].type) {
case VT_INT:
types[1+i] = &ffi_type_uint;
values[1+i] = &args[i].val.ivalue;
types[1+i] = &amp;ffi_type_uint;
values[1+i] = &amp;args[i].val.ivalue;
break;
case VT_DOUBLE:
types[1+i] = &ffi_type_double;
values[1+i] = &args[i].val.dvalue;
types[1+i] = &amp;ffi_type_double;
values[1+i] = &amp;args[i].val.dvalue;
break;
case VT_POINTER:
types[1+i] = &ffi_type_pointer;
values[1+i] = &args[i].val.pvalue;
types[1+i] = &amp;ffi_type_pointer;
values[1+i] = &amp;args[i].val.pvalue;
break;
default:
abort(); /* Whoa! We're seriously hosed */
break;
}
}
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1,
&ffi_type_uint, types) == FFI_OK) {
ffi_call(&cif, (void (*)()) printf, &result, values);
if (ffi_prep_cif(&amp;cif, FFI_DEFAULT_ABI, vc+1,
&amp;ffi_type_uint, types) == FFI_OK) {
ffi_call(&amp;cif, (void (*)()) printf, &amp;result, values);
} else {
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
free(types);
@ -651,10 +668,10 @@ Much to your amazement, it even seems to work if you try it:
<blockquote>
<pre>
>>> import example
>>> example.printf("Grade: %s %d/60 = %0.2f%%\n", "Dave", 47, 47.0*100/60)
&gt;&gt;&gt; import example
&gt;&gt;&gt; example.printf("Grade: %s %d/60 = %0.2f%%\n", "Dave", 47, 47.0*100/60)
Grade: Dave 47/60 = 78.33%
>>>
&gt;&gt;&gt;
</pre>
</blockquote>
@ -662,7 +679,7 @@ Of course, there are still some limitations to consider:
<blockquote>
<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)
</pre>
</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
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
@ -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
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
@ -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
pointer to a pointer to function as described in the C++ ARM section
18.3.4).
</p>
<p>
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
are placed in <tt>arg2</tt>, <tt>arg3</tt>, and so forth. For example:
</p>
<blockquote>
<pre>
%feature("action") Foo::bar {
...
result = arg1->bar(arg2, arg3, etc.);
result = arg1-&gt;bar(arg2, arg3, etc.);
...
}
</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
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
@ -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
between wrapper-specific information and the declaration of the function itself. The idea here is that
you might structure your interface like this:
</p>
<blockquote>
<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.
Also, be aware of the platform dependencies and reliability issues that
this will introduce. Good luck.
</p>
<p><hr>
<hr>
<address>SWIG 1.3 - Last Modified : March 24, 2002</address>
</body>

View file

@ -5,33 +5,33 @@
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>12 Warning Messages</H1>
<H1><a name="Warnings"></a>14 Warning Messages</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Introduction</a>
<li><a href="#n3">Warning message suppression</a>
<li><a href="#n4">Enabling additional warnings</a>
<li><a href="#n5">Issuing a warning message</a>
<li><a href="#n6">Commentary</a>
<li><a href="#n7">Warnings as errors</a>
<li><a href="#n8">Message output format</a>
<li><a href="#n9">Warning number reference</a>
<li><a href="#Warnings_nn2">Introduction</a>
<li><a href="#Warnings_nn3">Warning message suppression</a>
<li><a href="#Warnings_nn4">Enabling additional warnings</a>
<li><a href="#Warnings_nn5">Issuing a warning message</a>
<li><a href="#Warnings_nn6">Commentary</a>
<li><a href="#Warnings_nn7">Warnings as errors</a>
<li><a href="#Warnings_nn8">Message output format</a>
<li><a href="#Warnings_nn9">Warning number reference</a>
<ul>
<li><a href="#n10">Deprecated features (100-199)</a>
<li><a href="#n11">Preprocessor (200-299)</a>
<li><a href="#n12">C/C++ Parser (300-399)</a>
<li><a href="#n13">Types and typemaps (400-499) </a>
<li><a href="#n14">Code generation (500-599)</a>
<li><a href="#n15">Language module specific (800-899) </a>
<li><a href="#n16">User defined (900-999)</a>
<li><a href="#Warnings_nn10">Deprecated features (100-199)</a>
<li><a href="#Warnings_nn11">Preprocessor (200-299)</a>
<li><a href="#Warnings_nn12">C/C++ Parser (300-399)</a>
<li><a href="#Warnings_nn13">Types and typemaps (400-499) </a>
<li><a href="#Warnings_nn14">Code generation (500-599)</a>
<li><a href="#Warnings_nn15">Language module specific (800-899) </a>
<li><a href="#Warnings_nn16">User defined (900-999)</a>
</ul>
<li><a href="#n17">History</a>
<li><a href="#Warnings_nn17">History</a>
</ul>
<!-- 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:
@ -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
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.
@ -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
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
@ -143,6 +143,7 @@ When <tt>-Wall</tt> is used, all other warning filters are disabled.
<p>
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:
</p>
<blockquote>
<pre>
@ -169,7 +170,7 @@ or
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>.
<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
@ -187,6 +188,7 @@ your own warnings, make sure you don't use numbers defined in the table at the e
<p>
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:
</p>
<blockquote>
<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.
<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
@ -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
no obvious recovery. There is no mechanism for suppressing error
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
option. This will cause SWIG to exit with a non successful exit code if a
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
@ -246,10 +249,10 @@ $ swig -python -Fmicrosoft example.i
example.i(4): Syntax error in input.
</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>
@ -275,7 +278,7 @@ example.i(4): Syntax error in input.
<li>120. Deprecated command line option (-c).
</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>
@ -283,7 +286,7 @@ example.i(4): Syntax error in input.
<li>202. Could not evaluate 'expr'.
</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>
@ -330,7 +333,7 @@ example.i(4): Syntax error in input.
<li>368. operator/= ignored.
<li>369. operator%= ignored.
<li>370. operator^= ignored.
<li>371. operator&= ignored.
<li>371. operator&amp;= ignored.
<li>372. operator|= ignored.
<li>373. operator&lt;&lt; ignored.
<li>374. operator&gt;&gt;ignored.
@ -357,7 +360,7 @@ example.i(4): Syntax error in input.
<li>395. operator delete[] ignored.
</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>
@ -379,7 +382,7 @@ example.i(4): Syntax error in input.
<li>468. No 'throw' typemap defined for exception type 'type'.
</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>
@ -390,7 +393,7 @@ example.i(4): Syntax error in input.
<li>505. Variable length arguments discarded.
<li>506. Can't wrap varargs with keyword arguments enabled.
<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>510. Friend function '<em>name</em>' ignored.
<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.
</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>
@ -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#).
</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.
<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.
<p><hr>
<hr>
<address>SWIG 1.3 - Last Modified : June 28, 2003</address>
</body>
</html>

View file

@ -5,35 +5,35 @@
</head>
<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 -->
<ul>
<li><a href="#n2">Installation on Windows</a>
<li><a href="#Windows_nn2">Installation on Windows</a>
<ul>
<li><a href="#n3">Windows Executable</a>
<li><a href="#Windows_nn3">Windows Executable</a>
</ul>
<li><a href="#n4">SWIG Windows Examples</a>
<li><a href="#examples">SWIG Windows Examples</a>
<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>
<li><a href="#n6">Python</a>
<li><a href="#n7">TCL</a>
<li><a href="#n8">Perl</a>
<li><a href="#n9">Java</a>
<li><a href="#n10">Ruby</a>
<li><a href="#n11">C#</a>
<li><a href="#Windows_nn6">Python</a>
<li><a href="#Windows_nn7">TCL</a>
<li><a href="#Windows_nn8">Perl</a>
<li><a href="#Windows_nn9">Java</a>
<li><a href="#Windows_nn10">Ruby</a>
<li><a href="#Windows_nn11">C#</a>
</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>
<li><a href="#n13">SWIG on Cygwin and MinGW</a>
<li><a href="#Windows_nn13">SWIG on Cygwin and MinGW</a>
<ul>
<li><a href="#n14">Building swig.exe on Windows</a>
<li><a href="#swig_exe">Building swig.exe on Windows</a>
<ul>
<li><a href="#n15">Building swig.exe using MinGW and MSYS</a>
<li><a href="#n16">Building swig.exe using Cygwin</a>
<li><a href="#n17">Building swig.exe alternatives</a>
<li><a href="#Windows_nn15">Building swig.exe using MinGW and MSYS</a>
<li><a href="#Windows_nn16">Building swig.exe using Cygwin</a>
<li><a href="#Windows_nn17">Building swig.exe alternatives</a>
</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>
<!-- 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.
<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:
@ -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++.
</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.
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>
<a name="n4"></a><H2>2.2 SWIG Windows Examples</H2>
<H2><a name="examples"></a>3.2 SWIG Windows Examples</H2>
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).
<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.
@ -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 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>
@ -103,7 +101,7 @@ PYTHON_INCLUDE: d:\python21\include<br>
PYTHON_LIB: d:\python21\libs\python21.lib<br>
</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>
@ -114,7 +112,7 @@ TCL_INCLUDE: d:\tcl\include<br>
TCL_LIB: d:\tcl\lib\tcl83.lib<br>
</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>
@ -125,7 +123,7 @@ PERL5_INCLUDE: D:\nsPerl5.004_04\lib\CORE<br>
PERL5_LIB: D:\nsPerl5.004_04\lib\CORE\perl.lib<br>
</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>
@ -136,7 +134,7 @@ JAVA_INCLUDE: d:\jdk1.3\include<br>
JAVA_BIN: d:\jdk1.3\bin<br>
</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>
@ -147,25 +145,24 @@ RUBY_INCLUDE: D:\ruby\lib\ruby\1.6\i586-mswin32<br>
RUBY_LIB: D:\ruby\lib\mswin32-ruby16.lib<br>
</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.
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.
<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.
<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.
<a name="swig_exe"></a>
<a name="n14"></a><H3>2.3.1 Building swig.exe on Windows</H3>
<H3><a name="swig_exe"></a>3.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.
@ -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.
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>
@ -182,7 +179,7 @@ Normally this is not needed, so most people will want to ignore this section.
</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.
@ -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.
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.
<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
@ -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.
<a name="examples_cygwin"></a>
<a name="n18"></a><H3>2.3.2 Running the examples on Windows using Cygwin</H3>
<H3><a name="examples_cygwin"></a>3.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 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.
<p>
</body>
</html>

View file

@ -1,96 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG1.3 Documentation</title>
<title>SWIG-1.3 Documentation</title>
</head>
<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)
<p>
<b>Authors:</b>
The SWIG documentation is available in one of the following formats.
<ul>
<li>David Beazley (beazley@cs.uchicago.edu)
<li>William Fulton (wsf@fultondesigns.co.uk)
<li>Matthias Köppe (mkoeppe@mail.math.uni-magdeburg.de)
<li>Lyle Johnson (lyle@users.sourceforge.net)
<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
<li>HTML documentation with one chapter per page.
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>HTML documentation on a <a href="SWIGDocumentation.html">single HTML page</a>.</li>
<li><a href="SWIGDocumentation.pdf">PDF document</a>.</li>
</ul>
</body>