Overhaul updating to what SWIG really does - ie more emphasis on proxy classes over the low level accessor functions
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@9178 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
a3a7b4df66
commit
58e5a31f75
1 changed files with 349 additions and 380 deletions
|
|
@ -124,9 +124,8 @@ type checking, error handling, and other low-level details of the C++ binding.
|
|||
These wrappers are also sufficient to bind C++ into any target language
|
||||
that supports built-in procedures. In some sense, you might view this
|
||||
layer of wrapping as providing a C library interface to C++.
|
||||
Optionally, SWIG can also generate proxy classes
|
||||
that provide a natural OO interface to the underlying code. These proxies
|
||||
are built on top of the low-level procedural wrappers and are typically
|
||||
On top of the low-level procedural (flattened) interface, SWIG generates proxy classes
|
||||
that provide a natural object-oriented (OO) interface to the underlying code. The proxy classes are typically
|
||||
written in the target language itself. For instance, in Python, a real
|
||||
Python class is used to provide a wrapper around the underlying C++ object.
|
||||
</p>
|
||||
|
|
@ -134,8 +133,8 @@ Python class is used to provide a wrapper around the underlying C++ object.
|
|||
<p>
|
||||
It is important to emphasize that SWIG takes a deliberately
|
||||
conservative and non-intrusive approach to C++ wrapping. SWIG does not
|
||||
encapsulate C++ classes inside special C++ adaptor or proxy classes,
|
||||
it does not rely upon templates, nor does it use C++ inheritance when
|
||||
encapsulate C++ classes inside a special C++ adaptor, it does not rely
|
||||
upon templates, nor does it add in additional C++ inheritance when
|
||||
generating wrappers. The last thing that most C++ programs need is
|
||||
even more compiler magic. Therefore, SWIG tries to maintain a very
|
||||
strict and clean separation between the implementation of your C++
|
||||
|
|
@ -148,11 +147,10 @@ with C++, it is safe, simple, portable, and debuggable.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
Most of this chapter focuses on the low-level procedural interface to
|
||||
Some of this chapter focuses on the low-level procedural interface to
|
||||
C++ that is used as the foundation for all language modules. Keep in
|
||||
mind that most target languages also provide a high-level OO interface via
|
||||
proxy classes. A few general details about proxies can be found at the end of
|
||||
this chapter. However, more detailed coverage can be found in the documentation
|
||||
mind that the target languages also provide the high-level OO interface via
|
||||
proxy classes. More detailed coverage can be found in the documentation
|
||||
for each target language.
|
||||
</p>
|
||||
|
||||
|
|
@ -221,11 +219,271 @@ $ c++ example_wrap.o $(OBJS) -o example.so
|
|||
</div>
|
||||
|
||||
<p>
|
||||
Unfortunately, the process varies slightly on each machine. Make sure
|
||||
Unfortunately, the process varies slightly on each platform. Make sure
|
||||
you refer to the documentation on each target language for further
|
||||
details. The SWIG Wiki also has further details.
|
||||
</p>
|
||||
|
||||
<b>Compatibility Note:</b> Early versions of SWIG generated just a flattened low-level C style API to C++ classes by default.
|
||||
The <tt>-noproxy</tt> commandline option is recognised by many target languages and will generate just this
|
||||
interface as in earlier versions.
|
||||
|
||||
<H2><a name="SWIGPlus_nn38"></a>6.27 Proxy classes</H2>
|
||||
|
||||
|
||||
<p>
|
||||
In order to provide a natural mapping from C++ classes to the target language classes, SWIG's target
|
||||
languages mostly wrap C++ classes with special proxy classes. These
|
||||
proxy classes are typically implemented in the target language itself.
|
||||
For example, if you're building a Python module, each C++ class is
|
||||
wrapped by a Python proxy class. Or if you're building a Java module, each
|
||||
C++ class is wrapped by a Java proxy class.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_nn39"></a>6.27.1 Construction of proxy classes</H3>
|
||||
|
||||
|
||||
<p>
|
||||
Proxy classes are always constructed as an extra layer of wrapping that uses low-level
|
||||
accessor functions. To illustrate, suppose you had a
|
||||
C++ class like this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
~Foo();
|
||||
int bar(int x);
|
||||
int x;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Using C++ as pseudocode, a proxy class looks something like this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class FooProxy {
|
||||
private:
|
||||
Foo *self;
|
||||
public:
|
||||
FooProxy() {
|
||||
self = new_Foo();
|
||||
}
|
||||
~FooProxy() {
|
||||
delete_Foo(self);
|
||||
}
|
||||
int bar(int x) {
|
||||
return Foo_bar(self,x);
|
||||
}
|
||||
int x_get() {
|
||||
return Foo_x_get(self);
|
||||
}
|
||||
void x_set(int x) {
|
||||
Foo_x_set(self,x);
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Of course, always keep in mind that the real proxy class is written in the target language.
|
||||
For example, in Python, the proxy might look roughly like this:
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
class Foo:
|
||||
def __init__(self):
|
||||
self.this = new_Foo()
|
||||
def __del__(self):
|
||||
delete_Foo(self.this)
|
||||
def bar(self,x):
|
||||
return Foo_bar(self.this,x)
|
||||
def __getattr__(self,name):
|
||||
if name == 'x':
|
||||
return Foo_x_get(self.this)
|
||||
...
|
||||
def __setattr__(self,name,value):
|
||||
if name == 'x':
|
||||
Foo_x_set(self.this,value)
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Again, it's important to emphasize that the low-level accessor functions are always used by the
|
||||
proxy classes.
|
||||
Whenever possible, proxies try to take advantage of language features that are similar to C++. This
|
||||
might include operator overloading, exception handling, and other features.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_nn40"></a>6.27.2 Resource management in proxies</H3>
|
||||
|
||||
|
||||
<p>
|
||||
A major issue with proxies concerns the memory management of wrapped objects. Consider the following
|
||||
C++ code:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
~Foo();
|
||||
int bar(int x);
|
||||
int x;
|
||||
};
|
||||
|
||||
class Spam {
|
||||
public:
|
||||
Foo *value;
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Consider some script code that uses these classes:
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
f = Foo() # Creates a new Foo
|
||||
s = Spam() # Creates a new Spam
|
||||
s.value = f # Stores a reference to f inside s
|
||||
g = s.value # Returns stored reference
|
||||
g = 4 # Reassign g to some other value
|
||||
del f # Destroy f
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Now, ponder the resulting memory management issues. When objects are
|
||||
created in the script, the objects are wrapped by newly created proxy
|
||||
classes. That is, there is both a new proxy class instance and a new
|
||||
instance of the underlying C++ class. In this example, both
|
||||
<tt>f</tt> and <tt>s</tt> are created in this way. However, the
|
||||
statement <tt>s.value</tt> is rather curious---when executed, a
|
||||
pointer to <tt>f</tt> is stored inside another object. This means
|
||||
that the scripting proxy class <em>AND</em> another C++ class share a
|
||||
reference to the same object. To make matters even more interesting,
|
||||
consider the statement <tt>g = s.value</tt>. When executed, this
|
||||
creates a new proxy class <tt>g</tt> that provides a wrapper around the
|
||||
C++ object stored in <tt>s.value</tt>. In general, there is no way to
|
||||
know where this object came from---it could have been created by the
|
||||
script, but it could also have been generated internally. In this
|
||||
particular example, the assignment of <tt>g</tt> results in a second
|
||||
proxy class for <tt>f</tt>. In other words, a reference to <tt>f</tt>
|
||||
is now shared by two proxy classes <em>and</em> a C++ class.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Finally, consider what happens when objects are destroyed. In the
|
||||
statement, <tt>g=4</tt>, the variable <tt>g</tt> is reassigned. In
|
||||
many languages, this makes the old value of <tt>g</tt> available for
|
||||
garbage collection. Therefore, this causes one of the proxy classes
|
||||
to be destroyed. Later on, the statement <tt>del f</tt> destroys the
|
||||
other proxy class. Of course, there is still a reference to the
|
||||
original object stored inside another C++ object. What happens to it?
|
||||
Is the object still valid?
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To deal with memory management problems, proxy classes provide an API
|
||||
for controlling ownership. In C++ pseudocode, ownership control might look
|
||||
roughly like this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class FooProxy {
|
||||
public:
|
||||
Foo *self;
|
||||
int thisown;
|
||||
|
||||
FooProxy() {
|
||||
self = new_Foo();
|
||||
thisown = 1; // Newly created object
|
||||
}
|
||||
~FooProxy() {
|
||||
if (thisown) delete_Foo(self);
|
||||
}
|
||||
...
|
||||
// Ownership control API
|
||||
void disown() {
|
||||
thisown = 0;
|
||||
}
|
||||
void acquire() {
|
||||
thisown = 1;
|
||||
}
|
||||
};
|
||||
|
||||
class FooPtrProxy: public FooProxy {
|
||||
public:
|
||||
FooPtrProxy(Foo *s) {
|
||||
self = s;
|
||||
thisown = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class SpamProxy {
|
||||
...
|
||||
FooProxy *value_get() {
|
||||
return FooPtrProxy(Spam_value_get(self));
|
||||
}
|
||||
void value_set(FooProxy *v) {
|
||||
Spam_value_set(self,v->self);
|
||||
v->disown();
|
||||
}
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Looking at this code, there are a few central features:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Each proxy class keeps an extra flag to indicate ownership. C++ objects are only destroyed
|
||||
if the ownership flag is set.
|
||||
</li>
|
||||
|
||||
<li>When new objects are created in the target language, the ownership flag is set.
|
||||
</li>
|
||||
|
||||
<li>When a reference to an internal C++ object is returned, it is wrapped by a proxy
|
||||
class, but the proxy class does not have ownership.
|
||||
</li>
|
||||
|
||||
<li>In certain cases, ownership is adjusted. For instance, when a value is assigned to the member of
|
||||
a class, ownership is lost.
|
||||
</li>
|
||||
|
||||
<li>Manual ownership control is provided by special <tt>disown()</tt> and <tt>acquire()</tt> methods.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Given the tricky nature of C++ memory management, it is impossible for proxy classes to automatically handle
|
||||
every possible memory management problem. However, proxies do provide a mechanism for manual control that
|
||||
can be used (if necessary) to address some of the more tricky memory management problems.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_nn41"></a>6.27.3 Language specific details</H3>
|
||||
|
||||
|
||||
<p>
|
||||
Language specific details on proxy classes are contained in the chapters describing each target language. This
|
||||
chapter has merely introduced the topic in a very general way.
|
||||
</p>
|
||||
|
||||
<H2><a name="SWIGPlus_nn6"></a>6.5 Simple C++ wrapping</H2>
|
||||
|
||||
|
||||
|
|
@ -256,8 +514,7 @@ static void print(List *l);
|
|||
|
||||
<p>
|
||||
To generate wrappers for this class, SWIG first reduces the class to a collection of low-level C-style
|
||||
accessor functions. The next few sections describe this process. Later parts of the chapter describe a higher
|
||||
level interface based on proxy classes.
|
||||
accessor functions which are then used by the proxy classes.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_nn7"></a>6.5.1 Constructors and destructors</H3>
|
||||
|
|
@ -282,7 +539,7 @@ void delete_List(List *l) {
|
|||
|
||||
<p>
|
||||
Following the C++ rules for implicit constructor and destructors, SWIG
|
||||
will try to automatically generate them even when they are not
|
||||
will automatically assume there is one even when they are not
|
||||
explicitly declared in the class interface.
|
||||
</p>
|
||||
|
||||
|
|
@ -293,17 +550,17 @@ In general then:
|
|||
<ul>
|
||||
<li>
|
||||
If a C++ class does not declare any explicit constructor, SWIG will
|
||||
automatically generate one.
|
||||
automatically generate a wrapper for one.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
If a C++ class does not declare a explicit copy constructor, SWIG will
|
||||
automatically generate one.
|
||||
If a C++ class does not declare an explicit copy constructor, SWIG will
|
||||
automatically generate a wrapper for one if the <tt>%copyctor</tt> is used.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
If a C++ class does not declare an explicit destructor, SWIG will
|
||||
automatically create one.
|
||||
automatically generate a wrapper for one.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -334,16 +591,17 @@ class defines a non-public default constructor or destructor.
|
|||
|
||||
<p>
|
||||
SWIG should never generate a default constructor, copy constructor or
|
||||
default destructor for a class in which it is illegal to do so. In
|
||||
default destructor wrapper for a class in which it is illegal to do so. In
|
||||
some cases, however, it could be necessary (if the complete class
|
||||
declaration is not visible from SWIG, and one of the above rules is
|
||||
violated) or desired (to reduce the size of the final interface) to
|
||||
disable the implicit constructor/desctructor generation manually.
|
||||
violated) or desired (to reduce the size of the final interface) by
|
||||
manually disabling the implicit constructor/destructor generation.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To do so, the <tt>%nodefaultctor</tt> and <tt>%nodefaultdtor</tt>
|
||||
directives can be used. Note that these directives only affects the
|
||||
To manually disable these, the <tt>%nodefaultctor</tt> and <tt>%nodefaultdtor</tt>
|
||||
<a href="Customization.html#Customization_feature_flags">feature flag</a> directives
|
||||
can be used. Note that these directives only affects the
|
||||
implicit generation, and they have no effect if the default/copy
|
||||
constructors or destructor are explicitly declared in the class
|
||||
interface.
|
||||
|
|
@ -356,7 +614,7 @@ For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%nodefaultctor Foo; // Disable the default constructor for class Foo.
|
||||
class Foo { // No default constructor is generated, unless is declared
|
||||
class Foo { // No default constructor is generated, unless one is declared
|
||||
...
|
||||
};
|
||||
class Bar { // A default constructor is generated, if possible
|
||||
|
|
@ -372,12 +630,12 @@ The directive <tt>%nodefaultctor</tt> can also be applied "globally", as in:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%nodefaultctor; // Disable creation of default constructors
|
||||
class Foo { // No default constructor is generated, unless is declared
|
||||
class Foo { // No default constructor is generated, unless one is declared
|
||||
...
|
||||
};
|
||||
class Bar {
|
||||
public:
|
||||
Bar(); // The default constructor is generated, since is declared
|
||||
Bar(); // The default constructor is generated, since one is declared
|
||||
};
|
||||
%clearnodefaultctor; // Enable the creation of default constructors again
|
||||
</pre>
|
||||
|
|
@ -394,7 +652,7 @@ in well known cases. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%nodefaultdtor Foo; // Disable the implicit/default destructor for class Foo.
|
||||
class Foo { // No destructor is generated, unless is declared
|
||||
class Foo { // No destructor is generated, unless one is declared
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
|
|
@ -418,11 +676,10 @@ those sections in the interface or using <tt>%nodefault</tt> to fix the problem.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> The above described <tt>%nodefault</tt>
|
||||
directive/<tt>-nodefault</tt> option, which disable both the default
|
||||
constructor and the the implicit destructors, could lead to memory
|
||||
leaks across the target languages, and is highly recommended you don't
|
||||
use them.
|
||||
<b>Note:</b> The <tt>%nodefault</tt>
|
||||
directive/<tt>-nodefault</tt> options described above, which disable both the default
|
||||
constructor and the implicit destructors, could lead to memory
|
||||
leaks, and so it is strongly recommended to not use them.
|
||||
</p>
|
||||
|
||||
|
||||
|
|
@ -529,8 +786,8 @@ then the copy constructor can be used as follows:
|
|||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
x = new_List() # Create a list
|
||||
y = new_List(x) # Copy list x
|
||||
x = List() # Create a list
|
||||
y = List(x) # Copy list x
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -561,6 +818,23 @@ Constructors such as <tt>X(const X &)</tt>, <tt>X(X &)</tt>, and
|
|||
<b>Note:</b> SWIG does <em>not</em> generate a copy constructor
|
||||
wrapper unless one is explicitly declared in the class. This differs
|
||||
from the treatment of default constructors and destructors.
|
||||
However, copy constructor wrappers can be generated if using the <tt>copyctor</tt>
|
||||
<a href="Customization.html#Customization_feature_flags">feature flag</a>. For example:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%copyctor List;
|
||||
|
||||
class List {
|
||||
public:
|
||||
List();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Will generate a copy constructor wrapper for <tt>List</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -611,7 +885,7 @@ It should be noted that SWIG does not <em>actually</em> create a C accessor
|
|||
function in the code it generates. Instead, member access such as
|
||||
<tt>obj->search(value)</tt> is directly inlined into the generated
|
||||
wrapper functions. However, the name and calling convention of the
|
||||
wrappers match the accessor function prototype described above.
|
||||
low-level procedural wrappers match the accessor function prototype described above.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_nn12"></a>6.5.6 Static members</H3>
|
||||
|
|
@ -624,11 +898,6 @@ transformations. For example, the static member function
|
|||
in the generated wrapper code.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Usually, static members are accessed as functions with names in which the class name has been
|
||||
prepended with an underscore. For example, <tt>List_print</tt>.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_member_data"></a>6.5.7 Member data</H3>
|
||||
|
||||
|
||||
|
|
@ -649,8 +918,9 @@ int List_length_set(List *obj, int value) {
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
A read-only member can be created using the <tt>%immutable</tt> and
|
||||
<tt>%mutable</tt> directives. For example, we probably wouldn't want
|
||||
A read-only member can be created using the <tt>%immutable</tt> and <tt>%mutable</tt>
|
||||
<a href="Customization.html#Customization_feature_flags">feature flag</a> directive.
|
||||
For example, we probably wouldn't want
|
||||
the user to change the length of a list so we could do the following
|
||||
to make the value available, but read-only.</p>
|
||||
|
||||
|
|
@ -700,7 +970,7 @@ public:
|
|||
</div>
|
||||
|
||||
<p>
|
||||
then access to the <tt>items</tt> member actually uses pointers. For example:
|
||||
then the low-level accessor to the <tt>items</tt> member actually uses pointers. For example:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -725,7 +995,7 @@ This can be somewhat unnatural for some types.
|
|||
For example, a user would expect the STL std::string class member variables to be wrapped as a string in the target language,
|
||||
rather than a pointer to this class.
|
||||
The const reference typemaps offer this type of marshalling, so there is a feature to tell SWIG to use the const reference typemaps rather than the pointer typemaps.
|
||||
It is the <tt>%naturalvar</tt> feature and is used as follows:
|
||||
It is the <tt>%naturalvar</tt> directive and is used as follows:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -745,7 +1015,9 @@ struct Foo {
|
|||
</div>
|
||||
|
||||
<p>
|
||||
The observant reader will notice that <tt>%naturalvar</tt> works like any other <a href="Customization.html#features">feature</a>, except it can also be attached to class types.
|
||||
The observant reader will notice that <tt>%naturalvar</tt> works like any other
|
||||
<a href="Customization.html#Customization_feature_flags">feature flag</a> directive,
|
||||
except it can also be attached to class types.
|
||||
The first of the example usages above show <tt>%naturalvar</tt> attaching to the <tt>List</tt> class.
|
||||
Effectively this feature changes the way accessors are generated to the following:
|
||||
</p>
|
||||
|
|
@ -765,7 +1037,7 @@ void Foo_items_set(Foo *self, const List &value) {
|
|||
In fact it is generally a good idea to use this feature globally as the reference typemaps have extra NULL checking compared to the pointer typemaps.
|
||||
A pointer can be NULL, whereas a reference cannot, so the extra checking ensures that the target language user does not pass in a value that translates
|
||||
to a NULL pointer and thereby preventing any potential NULL pointer dereferences.
|
||||
The <tt>%naturalvar</tt> feature will also apply to global variables in some language modules, eg C# and Java.
|
||||
The <tt>%naturalvar</tt> feature will apply to global variables in addition to member variables in some language modules, eg C# and Java.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -857,7 +1129,7 @@ The <a href="#ambiguity_resolution_renaming">Ambiguity resolution and renaming</
|
|||
also deals with using <tt>%rename</tt> and <tt>%ignore</tt> on methods with default arguments.
|
||||
If you are writing your own typemaps for types used in methods with default arguments, you may also need to write a <tt>typecheck</tt> typemap.
|
||||
See the <a href="Typemaps.html#Typemaps_overloading">Typemaps and overloading</a> section for details or otherwise
|
||||
use the <tt>compactdefaultargs</tt> feature as mentioned below.
|
||||
use the <tt>compactdefaultargs</tt> feature flag as mentioned below.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -865,7 +1137,8 @@ use the <tt>compactdefaultargs</tt> feature as mentioned below.
|
|||
Instead a single wrapper method was generated and the default values were copied into the C++ wrappers
|
||||
so that the method being wrapped was then called with all the arguments specified.
|
||||
If the size of the wrappers are a concern then this approach to wrapping methods with default arguments
|
||||
can be re-activated by using the <tt>compactdefaultargs</tt> <a href="Customization.html#features">feature</a>.
|
||||
can be re-activated by using the <tt>compactdefaultargs</tt>
|
||||
<a href="Customization.html#Customization_feature_flags">feature flag</a>.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -966,7 +1239,7 @@ Members declared as <tt>const</tt> are wrapped as read-only members and do not c
|
|||
|
||||
|
||||
<p>
|
||||
Friend declarations are not longer ignored by SWIG. For example, if
|
||||
Friend declarations are recognised by SWIG. For example, if
|
||||
you have this code:
|
||||
</p>
|
||||
|
||||
|
|
@ -999,7 +1272,7 @@ void blah(Foo *f);
|
|||
|
||||
<p>
|
||||
A friend declaration, as in C++, is understood to be in the same scope
|
||||
where the class is declared, hence, you can do
|
||||
where the class is declared, hence, you can have
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -1038,7 +1311,8 @@ public:
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
is accessed using a function similar to this:</p>
|
||||
has a low-level accessor
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
double Foo_bar(Foo *obj, double *a) {
|
||||
|
|
@ -1081,7 +1355,7 @@ public:
|
|||
</div>
|
||||
|
||||
<p>
|
||||
Generates code like this:
|
||||
Generates an accessor like this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -1221,7 +1495,7 @@ multiple inheritance.
|
|||
|
||||
<p> SWIG treats private or protected inheritance as close to the C++
|
||||
spirit, and target language capabilities, as possible. In most of the
|
||||
cases, this means that swig will parse the non-public inheritance
|
||||
cases, this means that SWIG will parse the non-public inheritance
|
||||
declarations, but that will have no effect in the generated code,
|
||||
besides the implicit policies derived for constructor and
|
||||
destructors.
|
||||
|
|
@ -1263,8 +1537,8 @@ public:
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
When wrapped into Python, we can now perform the following operations
|
||||
:</p>
|
||||
When wrapped into Python, we can perform the following operations (shown using the low level Python accessors):
|
||||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
$ python
|
||||
|
|
@ -1308,20 +1582,20 @@ the attributes <tt>x</tt> and <tt>y</tt> are generated as
|
|||
</p>
|
||||
|
||||
<p>
|
||||
Although the low-level C-like interface is functional, most language
|
||||
modules also produce a higher level OO interface using proxy classes.
|
||||
This approach is described later and can be used to provide a more natural C++ interface.
|
||||
Note that there is a one to one correlation between the low-level accessor functions and
|
||||
the proxy methods and therefore there is also a one to one correlation between
|
||||
the C++ class methods and the generated proxy class methods.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> For the best results, SWIG requires all
|
||||
base classes to be defined in an interface. Otherwise, you may get an
|
||||
base classes to be defined in an interface. Otherwise, you may get a
|
||||
warning message like this:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example:18. Nothing known about class 'Foo'. Ignored.
|
||||
example.i:18: Warning(401): Nothing known about base class 'Foo'. Ignored.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1335,7 +1609,8 @@ silence the warning, you might consider using the <tt>%import</tt>
|
|||
directive to include the file that defines <tt>Foo</tt>.
|
||||
<tt>%import</tt> simply gathers type information, but doesn't generate
|
||||
wrappers. Alternatively, you could just define <tt>Foo</tt> as an empty class
|
||||
in the SWIG interface.
|
||||
in the SWIG interface or use
|
||||
<a href="Warnings.html#Warnings_suppression">warning suppression</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -1502,66 +1777,19 @@ generated wrappers to correctly cast pointer values under inheritance
|
|||
</p>
|
||||
|
||||
<p>
|
||||
One might be inclined to fix this problem using some variation of
|
||||
<tt>dynamic_cast<></tt>. The only problem is that it doesn't
|
||||
work with <tt>void</tt> pointers, it requires RTTI support, and it
|
||||
only works with polymorphic classes (i.e., classes that define one or
|
||||
more virtual functions).
|
||||
Some of the language modules are able to solve the problem by storing multiple instance of the pointer, for example, <tt>A *</tt>,
|
||||
in the A proxy class and <tt>C *</tt> in the C proxy class. The correct cast can then be made:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The bottom line: learn to live with type-tagged pointers.
|
||||
</p>
|
||||
|
||||
<H2><a name="SWIGPlus_nn22"></a>6.14 Renaming</H2>
|
||||
|
||||
|
||||
<p>
|
||||
C++ member functions and data can be renamed with the <tt>%name</tt>
|
||||
directive. The <tt>%name</tt> directive only replaces the member
|
||||
function name. For example :</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
class List {
|
||||
public:
|
||||
List();
|
||||
%name(ListSize) List(int maxsize);
|
||||
~List();
|
||||
int search(char *value);
|
||||
%name(find) void insert(char *);
|
||||
%name(delete) void remove(char *);
|
||||
char *get(int n);
|
||||
int length;
|
||||
static void print(List *l);
|
||||
};
|
||||
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
This will create the functions <tt>List_find</tt>,
|
||||
<tt>List_delete</tt>, and a function named <tt>new_ListSize</tt> for
|
||||
the overloaded constructor.</p>
|
||||
|
||||
<p>
|
||||
The <tt>%name </tt>directive can be applied to all members including
|
||||
constructors, destructors, static functions, data members, and
|
||||
enumeration values.</p>
|
||||
|
||||
<p>
|
||||
The class name prefix can also be changed by specifying </p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%name(newname) class List {
|
||||
<div class="code">
|
||||
<pre>
|
||||
C *c = new C();
|
||||
void *p = (void *) c;
|
||||
...
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Although the <tt>%name()</tt> directive can be used to help deal with
|
||||
overloaded methods, it really doesn't work very well because it
|
||||
requires a lot of additional markup in your interface. Keep reading
|
||||
for a better solution.
|
||||
</p>
|
||||
int x = A_function((C *) p);
|
||||
int y = B_function((C *) p);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<H2><a name="SWIGPlus_overloaded_methods"></a>6.15 Wrapping Overloaded Functions and Methods</H2>
|
||||
|
||||
|
|
@ -2295,7 +2523,7 @@ than dynamically typed languages like Perl, Python, Ruby, and Tcl.
|
|||
|
||||
|
||||
<p>
|
||||
Starting in SWIG-1.3.10, C++ overloaded operator declarations can be wrapped.
|
||||
C++ overloaded operator declarations can be wrapped.
|
||||
For example, consider a class like this:
|
||||
</p>
|
||||
|
||||
|
|
@ -2534,7 +2762,7 @@ chapter for further details.
|
|||
|
||||
<p>
|
||||
<b>Compatibility note:</b> The <tt>%extend</tt> directive is a new
|
||||
name for the <tt>%addmethods</tt> directive. Since <tt>%addmethods</tt> could
|
||||
name for the <tt>%addmethods</tt> directive in SWIG1.1. Since <tt>%addmethods</tt> could
|
||||
be used to extend a structure with more than just methods, a more suitable
|
||||
directive name has been chosen.
|
||||
</p>
|
||||
|
|
@ -2543,7 +2771,7 @@ directive name has been chosen.
|
|||
|
||||
|
||||
<p>
|
||||
In all versions of SWIG, template type names may appear anywhere a type
|
||||
Template type names may appear anywhere a type
|
||||
is expected in an interface file. For example:
|
||||
</p>
|
||||
|
||||
|
|
@ -3842,7 +4070,7 @@ just a single catch handler for the base class, <tt>EBase</tt> will be generated
|
|||
|
||||
|
||||
<p>
|
||||
Starting with SWIG1.3.7, there is limited parsing support for pointers to C++ class members.
|
||||
Starting with SWIG-1.3.7, there is limited parsing support for pointers to C++ class members.
|
||||
For example:
|
||||
</p>
|
||||
|
||||
|
|
@ -4409,265 +4637,6 @@ using another tool if maintaining constness is the most important part
|
|||
of your project.
|
||||
</p>
|
||||
|
||||
<H2><a name="SWIGPlus_nn38"></a>6.27 Proxy classes</H2>
|
||||
|
||||
|
||||
<p>
|
||||
In order to provide a more natural API, SWIG's target
|
||||
languages wrap C++ classes with special proxy classes. These
|
||||
proxy classes are typically implemented in the target language itself.
|
||||
For example, if you're building a Python module, each C++ class is
|
||||
wrapped by a Python class. Or if you're building a Java module, each
|
||||
C++ class is wrapped by a Java class.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_nn39"></a>6.27.1 Construction of proxy classes</H3>
|
||||
|
||||
|
||||
<p>
|
||||
Proxy classes are always constructed as an extra layer of wrapping that uses the low-level
|
||||
accessor functions described in the previous section. To illustrate, suppose you had a
|
||||
C++ class like this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
~Foo();
|
||||
int bar(int x);
|
||||
int x;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Using C++ as pseudocode, a proxy class looks something like this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class FooProxy {
|
||||
private:
|
||||
Foo *self;
|
||||
public:
|
||||
FooProxy() {
|
||||
self = new_Foo();
|
||||
}
|
||||
~FooProxy() {
|
||||
delete_Foo(self);
|
||||
}
|
||||
int bar(int x) {
|
||||
return Foo_bar(self,x);
|
||||
}
|
||||
int x_get() {
|
||||
return Foo_x_get(self);
|
||||
}
|
||||
void x_set(int x) {
|
||||
Foo_x_set(self,x);
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Of course, always keep in mind that the real proxy class is written in the target language.
|
||||
For example, in Python, the proxy might look roughly like this:
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
class Foo:
|
||||
def __init__(self):
|
||||
self.this = new_Foo()
|
||||
def __del__(self):
|
||||
delete_Foo(self.this)
|
||||
def bar(self,x):
|
||||
return Foo_bar(self.this,x)
|
||||
def __getattr__(self,name):
|
||||
if name == 'x':
|
||||
return Foo_x_get(self.this)
|
||||
...
|
||||
def __setattr__(self,name,value):
|
||||
if name == 'x':
|
||||
Foo_x_set(self.this,value)
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Again, it's important to emphasize that the low-level accessor functions are always used to construct the
|
||||
proxy classes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Whenever possible, proxies try to take advantage of language features that are similar to C++. This
|
||||
might include operator overloading, exception handling, and other features.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_nn40"></a>6.27.2 Resource management in proxies</H3>
|
||||
|
||||
|
||||
<p>
|
||||
A major issue with proxies concerns the memory management of wrapped objects. Consider the following
|
||||
C++ code:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
~Foo();
|
||||
int bar(int x);
|
||||
int x;
|
||||
};
|
||||
|
||||
class Spam {
|
||||
public:
|
||||
Foo *value;
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Now, consider some script code that uses these classes:
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
f = Foo() # Creates a new Foo
|
||||
s = Spam() # Creates a new Spam
|
||||
s.value = f # Stores a reference to f inside s
|
||||
g = s.value # Returns stored reference
|
||||
g = 4 # Reassign g to some other value
|
||||
del f # Destroy f
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Now, ponder the resulting memory management issues. When objects are
|
||||
created in the script, the objects are wrapped by newly created proxy
|
||||
classes. That is, there is both a new proxy class instance and a new
|
||||
instance of the underlying C++ class. In this example, both
|
||||
<tt>f</tt> and <tt>s</tt> are created in this way. However, the
|
||||
statement <tt>s.value</tt> is rather curious---when executed, a
|
||||
pointer to <tt>f</tt> is stored inside another object. This means
|
||||
that the scripting proxy class <em>AND</em> another C++ class share a
|
||||
reference to the same object. To make matters even more interesting,
|
||||
consider the statement <tt>g = s.value</tt>. When executed, this
|
||||
creates a new proxy class <tt>g</tt> that provides a wrapper around the
|
||||
C++ object stored in <tt>s.value</tt>. In general, there is no way to
|
||||
know where this object came from---it could have been created by the
|
||||
script, but it could also have been generated internally. In this
|
||||
particular example, the assignment of <tt>g</tt> results in a second
|
||||
proxy class for <tt>f</tt>. In other words, a reference to <tt>f</tt>
|
||||
is now shared by two proxy classes <em>and</em> a C++ class.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Finally, consider what happens when objects are destroyed. In the
|
||||
statement, <tt>g=4</tt>, the variable <tt>g</tt> is reassigned. In
|
||||
many languages, this makes the old value of <tt>g</tt> available for
|
||||
garbage collection. Therefore, this causes one of the proxy classes
|
||||
to be destroyed. Later on, the statement <tt>del f</tt> destroys the
|
||||
other proxy class. Of course, there is still a reference to the
|
||||
original object stored inside another C++ object. What happens to it?
|
||||
Is it the object still valid?
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To deal with memory management problems, proxy classes always provide an API
|
||||
for controlling ownership. In C++ pseudocode, ownership control might look
|
||||
roughly like this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class FooProxy {
|
||||
public:
|
||||
Foo *self;
|
||||
int thisown;
|
||||
|
||||
FooProxy() {
|
||||
self = new_Foo();
|
||||
thisown = 1; // Newly created object
|
||||
}
|
||||
~FooProxy() {
|
||||
if (thisown) delete_Foo(self);
|
||||
}
|
||||
...
|
||||
// Ownership control API
|
||||
void disown() {
|
||||
thisown = 0;
|
||||
}
|
||||
void acquire() {
|
||||
thisown = 1;
|
||||
}
|
||||
};
|
||||
|
||||
class FooPtrProxy: public FooProxy {
|
||||
public:
|
||||
FooPtrProxy(Foo *s) {
|
||||
self = s;
|
||||
thisown = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class SpamProxy {
|
||||
...
|
||||
FooProxy *value_get() {
|
||||
return FooPtrProxy(Spam_value_get(self));
|
||||
}
|
||||
void value_set(FooProxy *v) {
|
||||
Spam_value_set(self,v->self);
|
||||
v->disown();
|
||||
}
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Looking at this code, there are a few central features:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Each proxy class keeps an extra flag to indicate ownership. C++ objects are only destroyed
|
||||
if the ownership flag is set.
|
||||
</li>
|
||||
|
||||
<li>When new objects are created in the target language, the ownership flag is set.
|
||||
</li>
|
||||
|
||||
<li>When a reference to an internal C++ object is returned, it is wrapped by a proxy
|
||||
class, but the proxy class does not have ownership.
|
||||
</li>
|
||||
|
||||
<li>In certain cases, ownership is adjusted. For instance, when a value is assigned to the member of
|
||||
a class, ownership is lost.
|
||||
</li>
|
||||
|
||||
<li>Manual ownership control is provided by special <tt>disown()</tt> and <tt>acquire()</tt> methods.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Given the tricky nature of C++ memory management, it is impossible for proxy classes to automatically handle
|
||||
every possible memory management problem. However, proxies do provide a mechanism for manual control that
|
||||
can be used (if necessary) to address some of the more tricky memory management problems.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_nn41"></a>6.27.3 Language specific details</H3>
|
||||
|
||||
|
||||
<p>
|
||||
Language specific details on proxy classes are contained in the chapters describing each target language. This
|
||||
chapter has merely introduced the topic in a very general way.
|
||||
</p>
|
||||
|
||||
<H2><a name="SWIGPlus_nn42"></a>6.28 Where to go for more information</H2>
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue